Trans
7/22/2006 1:34:00 PM
Ben Zealley wrote:
> 'allo
>
> Say I have two classes:
>
> class Bloke
> attr_reader :name
> def sellSoul(aDemon)
> aDemon.buySoul(self)
> end
> end
>
> class Demon
> def buySoul(aBloke)
> # if aBloke called the method, OK. Else, tell them where to go.
> puts("I bought #{aBloke.name}'s soul!")
> end
> end
>
> Tim = Bloke.new
> Tim.name = "Tim"
> Satan = Demon.new
> Tim.sellSoul(Satan)
>
> I would like the buySoul method to work only if the Bloke calling it is
> the same instance of Bloke named, but I can't find any way to determine
> what object called a given method. Does anyone have a suggestion?
Some might argue that you can't do thi, b/c in reality what you want to
do is flawed conceptually. Be that as it may, you're essentially asking
for the Binding.of_caller, a well known extension, but one that is far
from perfect too. Albiet, in your case, and most cases I have ever
considered, a "self_of_caller" would suffice --the whole binding is
generally overkill. In any case, it can be done generally if you pass a
block:
require 'facet/binding/self' # see below for this code
class Bloke
attr_reader :name
def sellSoul(aDemon)
aDemon.buySoul{self}
end
end
class Demon
def buySoul(&aBloke)
# if aBloke called the method, OK. Else, tell them where to go.
if aBloke.binding.self == Bloke
puts("I bought #{aBloke[].name}'s soul!")
else
puts "You know were to go!"
end
end
end
T.
P.S. binding/self + binding/eval:
class Binding
# Returns the self in the binding context.
def self()
@self ||= eval( "self" )
@self
end
# Evaluate a Ruby source code string (or block) in the binding
context
def eval( str ) #='', &blk )
Kernel.eval( str, self )
end
end