Question

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?

Was it helpful?

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.

OTHER TIPS

It's because method a is creating a local variable called somevar. It's just one of Ruby's little quirks. You can get around this by doing self.somevar = 'something' or @somevar = 'something'.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top