# Mommy, where do methods come from?

**URL:** <https://rubytalk.org/t/mommy-where-do-methods-come-from/3693>\
**Category:** ruby-talk\
**Created:** [18 December 2002 18:05 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693 "2002-12-18T18:05:20Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chris18](https://avatars.discourse-cdn.com/v4/letter/c/e8c25b/32.png) [@Chris18](https://rubytalk.org/u/Chris18)\
**Post date:** [18 December 2002 18:05 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/1 "2002-12-18T18:05:20Z")

</div>

(Sorry for the subject; couldn’t help myself! 🙂

My (quite serious) question:

Is there a way to tell in which module an object’s method was defined?

For example:

class Foo  
def to\_s; ‘foo’; end  
end

class Bar; end

foo = Foo.new  
bar = Bar.new

foo.methodClass :to\_s # Hopefully returns Foo.  
bar.methodClass :to\_s # Hopefully returns Object.

Furthermore, is there a way to tell all of the modules which did define a  
method for a given object?

foo.methodClasses :to\_s # Hopefully returns [Foo, Object].

Finally (and I’m sure I should know this one already), how would I call  
Object#to\_s on foo if I have already redefined to\_s? (Is this even  
possible?)

Many thanks,

Chris

---

<div class="post-metadata">

**Author:** ![Nobuyoshi\_Nakada](https://avatars.discourse-cdn.com/v4/letter/n/edb3f5/32.png) [@Nobuyoshi\_Nakada](https://rubytalk.org/u/Nobuyoshi_Nakada)\
**Post date:** [18 December 2002 18:50 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/2 "2002-12-18T18:50:23Z")

</div>

Hi,

> Is there a way to tell in which module an object’s method was defined?
> 
> For example:
> 
> class Foo  
> def to\_s; ‘foo’; end  
> end
> 
> class Bar; end
> 
> foo = Foo.new  
> bar = Bar.new

```
module Kernel
  def methodClass(m)
    m = "#{m}"
    self.class.ancestors.find {|c| c.instance_methods.include?(m)}
  end
end

```

> foo.methodClass :to\_s # Hopefully returns Foo.  
> bar.methodClass :to\_s # Hopefully returns Object.

But bar.to\_s is defined in Kernel.

Once method of Method returns original class was proposed, but  
wasn’t accepted because of its name.

> Furthermore, is there a way to tell all of the modules which did define a  
> method for a given object?
> 
> foo.methodClasses :to\_s # Hopefully returns [Foo, Object].

Replace find with find\_all in above.

> Finally (and I’m sure I should know this one already), how would I call  
> Object#to\_s on foo if I have already redefined to\_s? (Is this even  
> possible?)

Impossible outside redefined to\_s, unless it’s aliased.

> **···**
>
> At Thu, 19 Dec 2002 03:05:20 +0900, Chris Pine wrote:
> 
> –  
> Nobu Nakada

---

<div class="post-metadata">

**Author:** ![David\_Alan\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/278dde/32.png) [@David\_Alan\_Black1](https://rubytalk.org/u/David_Alan_Black1)\
**Post date:** [18 December 2002 18:52 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/3 "2002-12-18T18:52:07Z")

</div>

Hi –

> (Sorry for the subject; couldn’t help myself! 🙂
> 
> My (quite serious) question:
> 
> Is there a way to tell in which module an object’s method was defined?
> 
> For example:
> 
> class Foo  
> def to\_s; ‘foo’; end  
> end
> 
> class Bar; end
> 
> foo = Foo.new  
> bar = Bar.new
> 
> foo.methodClass :to\_s # Hopefully returns Foo.  
> bar.methodClass :to\_s # Hopefully returns Object.
> 
> Furthermore, is there a way to tell all of the modules which did define a  
> method for a given object?
> 
> foo.methodClasses :to\_s # Hopefully returns [Foo, Object].

class Object  
def mc(meth,mess)  
self.class.ancestors.send(mess) {|mod|  
mod.instance\_methods.include?(meth.to\_s)  
}  
end

```
def method_class(meth)
  mc(meth,:detect)
end

def method_classes(meth)
  mc(meth,:select)
end

```

end

p “”.method\_class(“to\_s”) # String  
p Object.new.method\_class(“to\_s”) # Kernel  
p “”.method\_classes(“to\_s”) # [String, Kernel]

class Foo  
def to\_s; end  
end

foo = Foo.new  
p foo.method\_classes(“to\_s”) # [Foo, Kernel]

David

> **···**
>
> On Thu, 19 Dec 2002, Chris Pine wrote:
> 
> –  
> David Alan Black  
> home: [dblack@candle.superlink.net](mailto:dblack@candle.superlink.net)  
> work: blackdav@shu.edu  
> Web: [http://pirate.shu.edu/~blackdav](http://pirate.shu.edu/~blackdav)

---

<div class="post-metadata">

**Author:** ![Gavin\_Sinclair](https://avatars.discourse-cdn.com/v4/letter/g/db5fbb/32.png) [@Gavin\_Sinclair](https://rubytalk.org/u/Gavin_Sinclair)\
**Post date:** [18 December 2002 22:06 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/4 "2002-12-18T22:06:25Z")

</div>

> Finally (and I’m sure I should know this one already), how would I call  
> Object#to\_s on foo if I have already redefined to\_s? (Is this even  
> possible?)

class Base  
def foo  
15  
end  
end

Now we want to access Base#foo in derived even though it’s overwritten.

class Derived  
alias\_method :old\_foo, :foo

def foo  
-72  
end

def bar  
old\_foo  
end  
end

I don’t think it’s a very nice way to do it, but then I’ve never needed to.

Gavin

> **···**
>
> From: “Chris Pine” [nemo@hellotree.com](mailto:nemo@hellotree.com)

---

<div class="post-metadata">

**Author:** ![Christoph1](https://avatars.discourse-cdn.com/v4/letter/c/85f322/32.png) [@Christoph1](https://rubytalk.org/u/Christoph1)\
**Post date:** [18 December 2002 22:32 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/5 "2002-12-18T22:32:04Z")

</div>

…

> ```
> module Kernel
> def methodClass(m)
> m = "#{m}"
> self.class.ancestors.find {|c| c.instance_methods.include?(m)}
> end
> end
> 
> ```

Here is a slightly extended version which (hopefully) allows  
for ``undef’s" and/or singletons methods.

> **···**
>
> [nobu.nokada@softhome.net](mailto:nobu.nokada@softhome.net) wrote
> 
> * * *
> 
> ## module Kernel def methodClass(m) m = m.to\_s # catch method undef’s respond\_to?(m) or return nil # meta class is first inline extended\_anc = self.class.ancestors.unshift(class \<\< self; self end) extended\_anc.find {|c| c.instance\_methods.include?(m) } end end
> 
> …
> 
> /Christoph

---

<div class="post-metadata">

**Author:** ![Nobuyoshi\_Nakada](https://avatars.discourse-cdn.com/v4/letter/n/edb3f5/32.png) [@Nobuyoshi\_Nakada](https://rubytalk.org/u/Nobuyoshi_Nakada)\
**Post date:** [19 December 2002 01:41 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/6 "2002-12-19T01:41:06Z")

</div>

Hi,

> Once method of Method returns original class was proposed, but  
> wasn’t accepted because of its name.

An alternative.

module Kernel  
def methodClass(m)  
/: (\S+?)(?:((\S+)))?#/ =~ method(m).inspect  
eval($2 || $1)  
end  
end

> **···**
>
> At Thu, 19 Dec 2002 03:50:23 +0900, [nobu.nokada@softhome.net](mailto:nobu.nokada@softhome.net) wrote:
> 
> –  
> Nobu Nakada

---

<div class="post-metadata">

**Author:** ![Bulat\_Ziganshin](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Bulat\_Ziganshin](https://rubytalk.org/u/Bulat_Ziganshin)\
**Post date:** [19 December 2002 05:41 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/7 "2002-12-19T05:41:28Z")

</div>

Hello nobu,

Wednesday, December 18, 2002, 9:50:23 PM, you wrote:

> > Finally (and I’m sure I should know this one already), how would I call  
> > Object#to\_s on foo if I have already redefined to\_s? (Is this even  
> > possible?)

> Impossible outside redefined to\_s, unless it’s aliased.

if Ruby will call some method before adding each method, it will be possible

> **···**
>
> –  
> Best regards,  
> Bulat [mailto:bulatz@integ.ru](mailto:bulatz@integ.ru)

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [18 December 2002 22:41 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/8 "2002-12-18T22:41:14Z")

</div>

Christoph wrote:

> module Kernel  
> def methodClass(m)  
> m = m.to\_s  
> # catch method undef’s  
> respond\_to?(m) or return nil  
> # meta class is first inline  
> extended\_anc = self.class.ancestors.unshift(class \<\< self; self end)  
> extended\_anc.find {|c| c.instance\_methods.include?(m) }  
> end  
> end

Hm. Since #respond\_to? is doing this work alread, maybe it would make  
sense for it to return the Module where it finds a method, instead of  
just true?

Sorta like how defined?(arg) returns not just a boolean value but the  
kind of thing arg is.

---

<div class="post-metadata">

**Author:** ![Nobuyoshi\_Nakada](https://avatars.discourse-cdn.com/v4/letter/n/edb3f5/32.png) [@Nobuyoshi\_Nakada](https://rubytalk.org/u/Nobuyoshi_Nakada)\
**Post date:** [19 December 2002 06:21 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/9 "2002-12-19T06:21:52Z")

</div>

Hi,

> **···**
>
> At Thu, 19 Dec 2002 14:41:28 +0900, Bulat Ziganshin wrote:
> 
> > > > Finally (and I’m sure I should know this one already), how would I call  
> > > > Object#to\_s on foo if I have already redefined to\_s? (Is this even  
> > > > possible?)
> > 
> > > Impossible outside redefined to\_s, unless it’s aliased.
> > 
> > if Ruby will call some method before adding each method, it will be possible
> 
> Unfortunately, such hooks are only Class#method\_added and so  
> on, which will be called after it.
> 
> –  
> Nobu Nakada

---

<div class="post-metadata">

**Author:** ![Christoph1](https://avatars.discourse-cdn.com/v4/letter/c/85f322/32.png) [@Christoph1](https://rubytalk.org/u/Christoph1)\
**Post date:** [19 December 2002 00:12 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/10 "2002-12-19T00:12:34Z")

</div>

…

> Hm. Since #respond\_to? is doing this work alread, maybe it would make  
> sense for it to return the Module where it finds a method, instead of  
> just true?
> 
> Sorta like how defined?(arg) returns not just a boolean value but the  
> kind of thing arg is.

Sounds like a very good idea to me …

/Christoph

> **···**
>
> “Joel VanderWerf” [vjoel@PATH.Berkeley.EDU](mailto:vjoel@PATH.Berkeley.EDU) wrote

---

<div class="post-metadata">

**Author:** ![Nobuyoshi\_Nakada](https://avatars.discourse-cdn.com/v4/letter/n/edb3f5/32.png) [@Nobuyoshi\_Nakada](https://rubytalk.org/u/Nobuyoshi_Nakada)\
**Post date:** [19 December 2002 01:35 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/11 "2002-12-19T01:35:40Z")

</div>

Hi,

> Christoph wrote:
> 
> > module Kernel  
> > def methodClass(m)  
> > m = m.to\_s  
> > # catch method undef’s  
> > respond\_to?(m) or return nil  
> > # meta class is first inline  
> > extended\_anc = self.class.ancestors.unshift(class \<\< self; self end)  
> > extended\_anc.find {|c| c.instance\_methods.include?(m) }  
> > end  
> > end
> 
> Hm. Since #respond\_to? is doing this work alread, maybe it would make  
> sense for it to return the Module where it finds a method, instead of  
> just true?

Maybe nice.

> Sorta like how defined?(arg) returns not just a boolean value but the  
> kind of thing arg is.

defined?(arg) returns a string represents type of arg or nil,  
not true/false.

> **···**
>
> At Thu, 19 Dec 2002 07:41:14 +0900, Joel VanderWerf wrote:
> 
> –  
> Nobu Nakada

---

<div class="post-metadata">

**Author:** ![Bulat\_Ziganshin](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Bulat\_Ziganshin](https://rubytalk.org/u/Bulat_Ziganshin)\
**Post date:** [19 December 2002 06:33 UTC](https://rubytalk.org/t/mommy-where-do-methods-come-from/3693/12 "2002-12-19T06:33:41Z")

</div>

Hello nobu,

Thursday, December 19, 2002, 9:21:52 AM, you wrote:

> > > > Finally (and I’m sure I should know this one already), how would I call  
> > > > Object#to\_s on foo if I have already redefined to\_s? (Is this even  
> > > > possible?)
> > 
> > > Impossible outside redefined to\_s, unless it’s aliased.
> > 
> > if Ruby will call some method before adding each method, it will be possible

> Unfortunately, such hooks are only Class#method\_added and so  
> on, which will be called after it.

class Class  
def method\_added  
puts “sorry, it’s too late to save prevous method definition”  
puts “… but i can save the current definition for future references”  
puts “… are you sure you are absolutely need to do IT?”  
if gets==“y”  
$secret\_hash[class][method] \<\< method\_definition  
end  
end  
end

classes.each { |class|  
class.methods.each { |method|  
$secret\_hash[class][method] \<\< method\_definition  
}  
}

> **···**
>
> –  
> Best regards,  
> Bulat [mailto:bulatz@integ.ru](mailto:bulatz@integ.ru)
