# Assigning blame?

**URL:** <https://www.ruby-forum.com/t/assigning-blame/99416>\
**Category:** Ruby\
**Created:** [July 22, 2006, 2:33pm UTC](https://www.ruby-forum.com/t/assigning-blame/99416 "2006-07-22T14:33:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![apocalympse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/898d66/32.png) [@apocalympse](https://www.ruby-forum.com/u/apocalympse)\
**Post date:** [July 22, 2006, 2:33pm UTC](https://www.ruby-forum.com/t/assigning-blame/99416/1 "2006-07-22T14:33:32Z")

</div>

'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?

Cheers

---

<div class="post-metadata">

**Author:** ![apocalympse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/898d66/32.png) [@apocalympse](https://www.ruby-forum.com/u/apocalympse)\
**Post date:** [July 22, 2006, 3:04pm UTC](https://www.ruby-forum.com/t/assigning-blame/99416/2 "2006-07-22T15:04:14Z")

</div>

Ben Z. wrote:

> 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?  
> Not quite what you’re after, but it has the same effect: make sellSoul  
> a private method, so that it’s only possible (without #send contortions)  
> for Tim to call sellSoul on self.

Other than that, I think you’ll be into checking object\_ids against  
constants at the top execution level, which isn’t particularly useful.  
You could pass the binding to buySoul, I guess, but that’s just as  
nasty.

---

<div class="post-metadata">

**Author:** ![apocalympse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/898d66/32.png) [@apocalympse](https://www.ruby-forum.com/u/apocalympse)\
**Post date:** [July 25, 2006, 9:37am UTC](https://www.ruby-forum.com/t/assigning-blame/99416/3 "2006-07-25T09:37:22Z")

</div>

> Some might argue that you can’t do thi, b/c in reality what you want to  
> do is flawed conceptually.

Thankyou for the code - but would you explain to me why it’s “flawed  
conceptually”? I’m still relatively new to OO thinking - if it’s  
improper to have a way of identifying the object that called one of  
your methods, I’d like to know why…

Cheers

---

<div class="post-metadata">

**Author:** ![apocalympse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/898d66/32.png) [@apocalympse](https://www.ruby-forum.com/u/apocalympse)\
**Post date:** [July 22, 2006, 3:35pm UTC](https://www.ruby-forum.com/t/assigning-blame/99416/4 "2006-07-22T15:35:28Z")

</div>

Ben Z. wrote:

> 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
