1

Here's the code:

class Something
   attr_accessor :x
   def initialize(x)
      @x = x
   end
   def get_x
      x
   end
end

something = Something.new(5)
something.get_x # => 5

Why interpreter returns 5 if x is just a local variable in get_x method? Thanks

3 Answers 3

5

x is also a method. attr_accessor :x adds x= and x to your class. So, get_x is calling the x method, and returning the value for @x. see http://www.rubyist.net/~slagell/ruby/accessors.html for details.

Sign up to request clarification or add additional context in comments.

Comments

4

attr_accessor :x adds two methods for you:

def x=(val)
  @x = val
end

def x
  @x
end

So you don't actually need get_x getter if you've added attr_accessor method.

UPD

So the question is

class Something
  attr_accessor :x
  def initialize(x)
    @x = x
  end
  def set_x=(new)
    x = new
  end
end

Why won't x = new call default x setter: because default x setter is an instance method so you can call it for an object (Something instance) but not in your class like you try.

10 Comments

But what if we have another method def set_x(new_x) x = new_x end, why interpreter doesn't assume that is x=(val) method?
you can write as many setters as you want. attr_accessor is just a "helper" it creates two methods for you, but you are free to create as much as you need
The question is not how to make better, it's compiler trick issue.
Oh wait now I see what you're saying. If you use 'self.x = new_x' it actually does do that. This just seems like trying to break the interpreter. You should always be explicit about what variable/method you want in internal code.
The other interesting edge case can be seen as the interpreter guesses if you're accessing a local variable or invoking a method on yourself. Try this: def x; "method"; end; p x; x = 42; p x. The first x invokes the method (because no local variable with that name exists), but the second identical x reads the local variable. Local variables mask methods in the same scope unless you prefix with self.
|
2

The attr_accessor defines a method x (and the setter x=) which gets called in get_x.

>> something.methods.grep /^x/
=> [:x, :x=]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.