instance method adding another instance method to the class

R

Raj Singh

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

Dave Bass

Raj said:
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.
 
R

Rick DeNatale

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top