Reputation: 3304
This is my third day doing ruby and I am stuck with this problem:
2.0.0-p0 :001 > class SomeClass
2.0.0-p0 :002?> attr_accessor:a_var
2.0.0-p0 :003?> def initialize
2.0.0-p0 :004?> a_var = Hash.new
2.0.0-p0 :005?> puts "Initialized #{a_var.class}"
2.0.0-p0 :006?> end
2.0.0-p0 :007?> def a_fun
2.0.0-p0 :008?> puts "Initialized #{a_var.class}"
2.0.0-p0 :009?> end
2.0.0-p0 :010?> end
=> nil
2.0.0-p0 :011 > some_obj = SomeClass.new
Initialized Hash
=> #<SomeClass:0x007f9d1d809118>
2.0.0-p0 :012 > some_obj.a_fun
Initialized NilClass
=> nil
2.0.0-p0 :013 >
As you can see, the member variable a_var gets initialized inside in the initialize
method but the value is lost when a_fun
method is called.
I could not find anyone else facing this issue online.
Can someone please point me to my mistake please?
Upvotes: 0
Views: 389
Reputation: 61935
In a_var = x
, a_var
is treated as a local variable because it lacks the appropriate @
sigil and it appears on the left-hand side in an assignment. As such, the assignment has no effect outside the scope of the initialize method.
Let's look at some different, but similar cases:
a_var = x # assign to local/lexical variable
self.a_var = x # invoke a_var= method ("setter")
a_var # access local variable if it exists in scope
# OR invoke self.a_var method ("getter")
@a_var = x # assign to instance variable
Because attr_accessor
is used, I suspect that the following is desired ..
def initialize
self.a_var = Hash.new
..
end
.. and leave every other a_var
access the same (see the rule table above).
Now, as a "well-known" implementation detail, attr_accessor :x
uses the instance variable @x
internally, so using @a_var
directly (i.e. for the assignment) would also work.
Upvotes: 3
Reputation: 39733
You can only carry instance (have @ before them) variables around from method to method inside of an instance. local variables (have no symbols before them) are limited to their methods or other anonymous enclosures (blocks, etc)
attr_accessor accesses instance variables only. Not local variables.
And your ruby variable naming needs some work. Try to make your variable names match what you're doing. i.e. in this instance you're just trying to discover abstract properties of ruby's structure. Try using @x
& @y
so the rest of us won't get thrown by your inscrutable naming schemes
Upvotes: 1
Reputation: 118289
change this a_var = Hash.new
to @a_var = Hash.new
in your #initialize
method.
Corrected code:
class SomeClass
attr_accessor:a_var
def initialize
@a_var = Hash.new
puts "Initialized #{a_var.class}"
end
def a_fun
puts "Initialized #{a_var.class}"
end
end
some_obj = SomeClass.new
some_obj.a_fun
# >> Initialized Hash
# >> Initialized Hash
Upvotes: 1