Even though the bar.nil? in fuga should not be true, it gets overwritten by the local variable preceding the if and thus evaluates true.
I'd expect a behavior like below. It's really weird to get my class attributes overridden by a local variable that shouldn't even be evaluated.
I think hanmac already gave the correct answer so there is no point in me adding
much to it. :)
Note that you could specifically point ruby to call the getter method in the
line hanmac pointed out, rather than using:
bar = 0 if bar.nil?
You could use:
bar = 0 if self.bar.nil?
And then the result would change.
I took the liberty to reformat your input, so that other people have
an easier time to copy/paste; the "irb" comments interfere there. I
also commented it a tiny bit to make it more clear.
Even the old pickaxe mentions that ruby may behave slightly unexpected
in regards to assignments and local variables when it comes to nil
class Foo
attr_accessor :bar
def initialize
self.bar = 1 # Assigned 1 to @bar.
end
def hoge
bar # Call reader method bar().
end
def fuga
bar = 0 if bar.nil?
[bar, self.bar]
end
def baz
if bar.nil?
bar = 0
end
end
end
foo = Foo.new
p foo.bar
p foo.hoge
p foo.fuga
p foo.bar
p foo.baz
Even the old pickaxe mentions that ruby may behave slightly unexpected
in regards to assignments and local variables when it comes to nil
I still can't consider this correct behavior. Aren't the multi-line and the single-line ways of writing if supposed to be equivalent?
I took the liberty to reformat your input, so that other people have
an easier time to copy/paste; the "irb" comments interfere there. I
also commented it a tiny bit to make it more clear.