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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.