Sean O'Halpin
7/23/2006 9:55:00 PM
On 7/23/06, Ashley Moran <work@ashleymoran.me.uk> 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