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.

···

--
Posted via http://www.ruby-forum.com/\.

Michal Gabrukiewicz 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 Williamsson

thanks jari ... i can see clearly now :slight_smile:

Jari Williamsson wrote:

Michal Gabrukiewicz 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 Williamsson

--
Posted via http://www.ruby-forum.com/\.

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 Williamsson <jari.williams...@mailbox.swipnet.se> wrote:

Michal Gabrukiewicz 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 Williamsson

Jari Williamsson wrote:

Michal Gabrukiewicz 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

--
Posted via http://www.ruby-forum.com/\.

One minor correction to an otherwise perfectly fine explanation:

Jari Williamsson <jari.williamsson@mailbox.swipnet.se> 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.

···

--
s=%q( Daniel Martin -- martin@snowplow.org
       puts "s=%q(#{s})",s.to_a.last )
       puts "s=%q(#{s})",s.to_a.last

Cláudio Caseiro wrote:

Jari Williamsson wrote:

Michal Gabrukiewicz 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"

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

- Charlie