Ruby: access to attr_accessor's method from internal method

attr-accessor, ruby

Solution

`attr_accessor :somevar` references the instance variable `@somevar`. Instance variables must be preceded by the `@` sign. All other variables like 'somevar' without an `@` sign in a method are just local variables to that method or scope, not instance variables for the object.

Thus, changing the first line in method "a" to

@somevar = 'something'

will result in the answer you expect.

Related note: you don't have to declare instance variables in Ruby, you just create them with `@somevar` type notation. The `attr_accessor` method creates setters and getters for that instance variable.

Methods in Ruby are attached to objects, so in order for class A to invoke its own somevar setter method, you would need to write `self.somevar = 'something'`, otherwise the Ruby parser thinks you are just creating a local variable.

This could be confusing because you could invoke method `a` from `b`, by just doing:

def b
  send :somevar=,'something'
  puts @somevar
  a  # would invoke its own method 'a'
end

But the setter method `somevar=` is ambiguous with creating a local variable with the same notation:

somevar='something'  # Ruby assumes you want to create a local variable

So to call the somevar setter method you need to explicitly say that you are calling the method on self with:

self.somevar = 'something'

When you called `send :somevar=,'something'` you were invoking the somevar instance method also.

Problem

I have a code: ``` class A attr_accessor :somevar def a somevar = 'something' puts @somevar end def b send :somevar=, 'something' puts @somevar end end A.new.a #=> nil A.new.b #=> 'something' ``` Why is there a difference? Why can't I just assign an instance variable through a writer? But why local variable has been created instead of method (setter) has been called?

Original source