[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

instance method adding another instance method to the class

Raj Singh

5/29/2008 7:26:00 PM

class Person
end

p = Person.new

def p.something
def speaks
puts 'i speak'
end
end

p.something
Person.new.speaks


I am trying to understand why the last line is working.

When p.something is executed then the self is 'p object'. Now method
speaks is being defined while the self is p. Since speaks is an instance
method a method should be defined in p's metaclass. But p's meta class
is not Person.

Any one cares to explain how method speaks get defined as an instance
method for Person class.
--
Posted via http://www.ruby-....

2 Answers

Dave Bass

5/29/2008 9:32:00 PM

0

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.

--
Posted via http://www.ruby-....

Rick DeNatale

5/29/2008 10:09:00 PM

0

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.denh...