On Thu, May 29, 2008 at 5:31 PM, Dave Bass <davebass / musician.org> wrote:
> Raj Singh wrote:
>> Any one cares to explain how method speaks get defined as an instance
>> method for Person class.
>
> It's not necessary to instantiate Person; changing the last line to
> Person.speaks also works. This indicates that speak is being defined as
> a class method. This can be confirmed if you put a "p self" line in:
>
> class Person
> end
>
> p = Person.new
>
> def p.something
>  def speaks
>    puts 'i speak'
>    p self
>  end
> end
>
> p.something
> Person.speaks
>
> which gives:
>
> i speak
> Person
>
> How it works is beyond me though.

It's because a nested def doesn't define a method in the class of the
receiver of the outer method. So in this case it's just as if the code
was written simply:

def speaks
  puts "I speak
end

except that this doesn't get evaluated until the something method is run.

So it ends up defining this method, as all top-level methods are, in
the Kernel module, so any object will respond to speaks.

To get what I think the OP intended, which is to define speaks as a
singleton method when the singleton method something is run, try

def p.something
   def self.speaks
      puts "I speak"
   end
end

-- 
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/