Problem with 'self'. behaves different on setting and gettin

hello,
i have a question according ‘self’. I have setup a small simple scenario
to simulate the problem.

This following small program works fine …

class User
def set_foo
self.x = ‘1’
end
def get_foo
x
end
def x=(val)
@x = val
end
def x
@x
end
end

u = User.new
u.set_foo
puts(u.x)
puts(u.get_foo)

when i now remove the ‘self’ within the method ‘set_foo’ it does not set
the values any more.

class User
def set_foo
x = ‘1’
end
def get_foo
x
end
def x=(val)
@x = val
end
def x
@x
end
end

u = User.new
u.set_foo
puts(u.x)
puts(u.get_foo)

so my 1st question is: why doesnt the ‘set_foo’ method calls the ‘x’
method if i remove the self?
THE INTERESTING THING: ‘get_foo’ works with ‘x’ and ‘self.x’

and the 2nd question: when should i use self now and when not and why is
there this strange behavoir?

thanks for looking into this.

Michal G. wrote:

so my 1st question is: why doesnt the ‘set_foo’ method calls the ‘x’
method if i remove the self?

Because it now thinks that x is a local variable. This is one of the
basics of Ruby.

If you use NetBeans, the editor will alert you about these kind of
things in the colored syntax.

THE INTERESTING THING: ‘get_foo’ works with ‘x’ and ‘self.x’

Yes, but with different result behind the scenes. ‘x’ is the same as
‘x()’, while ‘self.x’ is the same a ‘@x

and the 2nd question: when should i use self now and when not and why is
there this strange behavoir?

You should use self when a left-side argument can be interpreted as a
local variable.

Best regards,

Jari W.

thanks jari … i can see clearly now :slight_smile:

Jari W. wrote:

Michal G. wrote:

so my 1st question is: why doesnt the ‘set_foo’ method calls the ‘x’
method if i remove the self?

Because it now thinks that x is a local variable. This is one of the
basics of Ruby.

thats the important thing!

If you use NetBeans, the editor will alert you about these kind of
things in the colored syntax.

THE INTERESTING THING: ‘get_foo’ works with ‘x’ and ‘self.x’

Yes, but with different result behind the scenes. ‘x’ is the same as
‘x()’, while ‘self.x’ is the same a ‘@x

and the 2nd question: when should i use self now and when not and why is
there this strange behavoir?

You should use self when a left-side argument can be interpreted as a
local variable.

Best regards,

Jari W.

Here’s a small example to illustrate Jari’s point:

class User
attr_accessor :x

def foo
self.x = 1
puts x # => 1
x = 2
puts x # => 2
puts self.x # => 1
end
end

User.new.foo

Any assignment without an explicit receiver will set a local
variable. You also need to use self if the method you’re calling is
shadowed by a local variable with the same name, as in my example
above. Finally, you must use self if the method you’re calling is a
reserved word, such as self.class.

Page 86 of the Pickaxe book (Programming Ruby) talks about this.

On Nov 30, 10:33 am, Jari W.

Jari W. wrote:

Michal G. wrote:

THE INTERESTING THING: ‘get_foo’ works with ‘x’ and ‘self.x’

Yes, but with different result behind the scenes. ‘x’ is the same as
‘x()’, while ‘self.x’ is the same a ‘@x

I think this is not correct. Since there are no local variable “x” in
method get_foo, bot “x” and “self.x” will send message x to self.

If you reopen class User:

class User
def x
“2”
end
end

Both x and self.x in get_foo will return “2”, even if @x is “1”

Regards,

Cláudio Caseiro

One minor correction to an otherwise perfectly fine explanation:

Jari W. [email protected] writes:

Yes, but with different result behind the scenes. ‘x’ is the same as
‘x()’, while ‘self.x’ is the same a ‘@x

Not quite. self.x is the same as x(), but:

self.x = …

is the same as self.x=(…). The connection to @x only happens
because of the definition for the x= method in the orginal post.

Cláudio Caseiro wrote:

method get_foo, bot “x” and “self.x” will send message x to self.

If you reopen class User:

class User
def x
“2”
end
end

Both x and self.x in get_foo will return “2”, even if @x is “1”

You are correct. Both are calls to the “x” method. The only difference
is that “self.x” will fail if “x” is private.

  • Charlie