Forum: Ruby [Newbie] Question about instance method scoping/parsing (?)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
De271a04fe7a67b884ce75404c1dcc61?d=identicon&s=25 Chris Gernon (kabigon)
on 2007-01-05 23:37
Can anyone explain to me what's going on here?

-------------------------------------
#!/usr/bin/env ruby -w

class Thingy
  attr_accessor :name

  def test
    puts "self.name: #{self.name}"
    puts "name:      #{name}"

    name ||= 'default value'

    puts "self.name: #{self.name}"
    puts "name:      #{name}"
  end
end

thing1 = Thingy.new
thing1.name = 'custom value'
thing1.test
-------------------------------------
$ ruby dditest.rb
self.name: custom value
name:      custom value
self.name: custom value
name:      default value
-------------------------------------

I thought calling a method without a receiver (i.e. name, name=) within
an instance method would always call that method on the current object.
Is this not true for setters (i.e. Thingy#name=)?

Additionally, why is the first instance of name interpreted as a method
call and the last instance interpreted as (I think) a local variable?

Thanks,
Chris
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2007-01-06 19:30
(Received via mailing list)
Hi --

On Sat, 6 Jan 2007, Chris Gernon wrote:

> I thought calling a method without a receiver (i.e. name, name=) within
> an instance method would always call that method on the current object.
> Is this not true for setters (i.e. Thingy#name=)?

It is not true for setters.  The way it works is that when the parser
sees:

   bareword = ...

it defines bareword as a local variable.  Therefore, you always need
an explicit receiver for that kind of method, so Ruby will know it's a
method.

There are some interesting side-effects from this.  For example:

   if false
     a = 1
   end

   puts a   # nil

Even though "a = 1" is never executed, it's picked up by the parser,
and a gets defined.  That's why "puts a" doesn't raise an "unknown
method or local variable" error.

> Additionally, why is the first instance of name interpreted as a method
> call and the last instance interpreted as (I think) a local variable?

If both are defined, the local variable takes precedence.  You can
force method interpretation with parentheses:

   name()

but of course in practice it's better not to reuse the names.


David
This topic is locked and can not be replied to.