I created some virtual attributes in a model in order to store
intermediate calculated values. I wanted to use
attr_accessor_with_default so that I could give the calculated values
an initial value to allow me to use += to easily accumulate values.
When I did so I came across some slightly perplexing behaviour which I
was wondering if anybody could explain to me.
When I tried to create a method in the class which used += on the bare
attribute it complained that the attribute was nil
D:\Data\Ruby\footy>ruby script\console
Loading development environment (Rails 2.0.2)
class Foo
attr_accessor_with_default :bar, 0
def increment_bar
bar += 1
end
end
=> nil
f = Foo.new
=> #<Foo:0x37b47d0>
f.increment_bar
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+
from (irb):4:in `increment_bar'
from (irb):8
On the other hand, if I referred to the attribute using the self
qualifier, everything worked fine.
D:\Data\Ruby\footy>ruby script\console
Loading development environment (Rails 2.0.2)
class Foo
attr_accessor_with_default :bar, 0
def increment_bar
self.bar += 1
end
end
=> nil
f = Foo.new
=> #<Foo:0x37b43c0>
f.increment_bar
=> 1
If someone is able to explain this in words of one syllable that would
be greatly appreciated.
I created some virtual attributes in a model in order to store
intermediate calculated values. I wanted to use
attr_accessor_with_default so that I could give the calculated values
an initial value to allow me to use += to easily accumulate values.
When I did so I came across some slightly perplexing behaviour which I
was wondering if anybody could explain to me.
When I tried to create a method in the class which used += on the bare
attribute it complained that the attribute was nil
D:\Data\Ruby\footy>ruby script\console
Loading development environment (Rails 2.0.2)
class Foo
attr_accessor_with_default :bar, 0
def increment_bar
bar += 1
end
end
=> nil
f = Foo.new
=> #<Foo:0x37b47d0>
f.increment_bar
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+
from (irb):4:in `increment_bar'
from (irb):8
On the other hand, if I referred to the attribute using the self
qualifier, everything worked fine.
D:\Data\Ruby\footy>ruby script\console
Loading development environment (Rails 2.0.2)
class Foo
attr_accessor_with_default :bar, 0
def increment_bar
self.bar += 1
end
end
=> nil
f = Foo.new
=> #<Foo:0x37b43c0>
f.increment_bar
=> 1
If someone is able to explain this in words of one syllable that would
be greatly appreciated.
When you go like this:
x = 1
the tongue by Matz thinks you want to set x to 1. And this:
x += 1 # change x to x plus 1
means (more or less) this:
x = x + 1
If you have a thing you can call (you know -- one of those things you
write with "def"), like this:
def x=(n)
and you want to run it, you have to use self (or, if not self, an apt
thing, like y or z or what have you):
self.x = 1
y.x = 2
so that the tongue by Matz knows you want to call that thing. It's a
case of "It could be this, or it could be that; please make it clear,
or I will fall back on the 'set x to n' view."
When you do bar+= 1, ruby thinks you are talking about the local
variable bar. When you do self.bar += 1, ruby knows that you're
talking about the method (you haven't defined a bar local variable but
saying bar += 1 causes one (with value nil) to spring into existance;
ruby local variable stuff is a little funky in places.