From: Sean O'Halpin Date: 2006-07-24T06:55:20+09:00 Subject: Re: get caller of method On 7/23/06, Ashley Moran wrote: > > On Jul 23, 2006, at 8:06 pm, thomas coopman wrote: > > > Hi, > > > > Does there exist a method to get the object or type of object that > > calls this method? > > > > for example: > > > > class Foo > > do > > end > > class Bar > > do > > end > > > > do > > if caller.kind_of?(Foo) > > puts "Foo" > > elsif caller.kind_of?(Bar) > > puts "Bar" > > end > > end > > > > Thanks! > > > > Thomas > > I'm assuming you meant something like: > > class Foo > def do_stuff > do_something > end > end > class Bar > def do_stuff > do_something > end > end > > def do_something > if caller.kind_of?(Foo) > puts "Foo" > elsif caller.kind_of?(Bar) > puts "Bar" > end > end > > since "do" is a reserved word in Ruby. > > In this case you can do the following: > > def do_something(b = binding) > case eval("self", b) > when Foo then "Called by Foo" > when Bar then "Bar told me to do it" > end > end > > Then you get: > Foo.new.do_stuff > => "Called by Foo" > > Bar.new.do_stuff > => "Bar told me to do it" > > Note however that it would be possible for a method to "lie" and pass > in another binding when the method is called. And also it won't work > in this case: > > class Foo > do_something > end > > because the calling object is an instance of Class, but you could use: > > def do_something(b = binding) > case eval("self.name", b) > when "Foo" then "Called when building Foo" > when "Bar" then "Bar's creator told me to do it" > end > end > > and you get: > class Foo > do_something > end > => "Called when building Foo" > > > Maybe there is a better way to do this but it's a starter for 10. > > > Ashley > Hi, It's not clear to me what you're doing with the binding. You don't need it for your example and it won't work the way you seem to think. The example below shows you don't need to do anything fancy to get hold of self: def do_something case self when Foo puts "Called by Foo" when Bar puts "Bar told me to do it" when Class case self.name when "Foo" puts "Class Foo did it" end end end class Foo def do_stuff do_something end end class Bar def do_stuff do_something end end Foo.new.do_stuff Bar.new.do_stuff class Foo do_something end __END__ Called by Foo Bar told me to do it Class Foo did it The next example shows that the binding you create in the argument list is local to the method definition, not to the caller (which I think is what you're thinking). def test_binding(str, b = binding) x = 2 p eval(str, b) end class Foo x = 1 test_binding "x", binding test_binding "x" end __END__ 1 2 Please feel free to correct me if I've gotten hold of the wrong end of the stick (it has been known ;) Regards, Sean