Getting a reference to the object which called a method


(Mathew Johnston) #1

Is it possible to get the same effect as the following, but without
having to pass self as an arguement?

···

class TestClass
def testMethod (calling_object)
puts calling_object.type
end
end

class AnotherClass
def do
TestClass.new.testMethod(self)
end
end

AnotherClass.new.do

This should output “AnotherClass”.


(Paul Brannan) #2

Yes, but all the solutions I know of are either slow or buggy (see
[ruby-talk:22963] for one such solution).

Why do you want to do this, anyway? It doesn’t sound like a good idea.

Paul

···

On Fri, Jun 07, 2002 at 03:44:19AM +0900, Mathew Johnston wrote:

Is it possible to get the same effect as the following, but without
having to pass self as an arguement?


(Jean-Hugues ROBERT) #3

Hello,

Is it possible to get the same effect as the following, but without
having to pass self as an arguement?

class TestClass
def testMethod (calling_object)
puts calling_object.type
end
end

class AnotherClass
def do
TestClass.new.testMethod(self)
end
end

AnotherClass.new.do
This should output “AnotherClass”.

Do you need to know about the calling object or do you intend it to
do something for you ? Anyways…

I had a similar issue to solve recently and it seems that “block” &
eval() may help here:

class TestClass
def testMethod( &block )
r = my_test_result
puts eval( “self”, block).type # “self” where block was defined
rescue Exception ex; r = ex
ensure
block.call( r) # Callback to signal test result
end
end

class AnotherClass
def do
TestClass.new.testMethod() do | r |
# Process test result r here
end
end
end

Warning: Not tested.

Depending on what you need, it is either the ability to get "self"
from a block or using a callback that may help you.

BTW: We are missing a caller() that would include bindings. With it
one could write: puts eval( “self”, caller( :Bindinds)[0]).type; to
achieve exactly what you want.

Yours,

Jean-Hugues

···

At 03:44 07/06/2002 +0900, you wrote:


Web: http://hdl.handle.net/1030.37/1.1
Phone: +33 (0) 4 92 27 74 17


(Mathew Johnston) #4

Hmm :slight_smile: What I’m trying to do is ensure that only the object which
created another object can call it’s methods. For example, object A
instantiates object B. In object B’s initialize method, I would set an
object variable (@creator), referencing the object that called .new. On
method calls, I would “raise ‘Method called by non-creator’ if [insert
method to get ref to caller object].id == @creator.id

Is there another way to do this?

Mat.

···

On Thu, 2002-06-06 at 14:25, Paul Brannan wrote:

On Fri, Jun 07, 2002 at 03:44:19AM +0900, Mathew Johnston wrote:

Is it possible to get the same effect as the following, but without
having to pass self as an arguement?

Yes, but all the solutions I know of are either slow or buggy (see
[ruby-talk:22963] for one such solution).

Why do you want to do this, anyway? It doesn’t sound like a good idea.

Paul


(Niklas Frykholm) #5

[Mathew Johnston]:

Hmm :slight_smile: What I’m trying to do is ensure that only the object which
created another object can call it’s methods. For example, object A
instantiates object B. In object B’s initialize method, I would set an
object variable (@creator), referencing the object that called .new. On
method calls, I would “raise ‘Method called by non-creator’ if [insert
method to get ref to caller object].id == @creator.id

Is there another way to do this?

I would probably do this by creating a proxy to the object with a safe
interface. Something like this:

class RealClass
	def initialize
		...
	end

	def safe_method
		...
	end

	def dangerous_method
		...
	end
end

class SafeProxy
	def initialize(real_object)
		@real_object = real_object
	end

	def safe_method
		@real_object.safe_method
	end
end

The creator object a would create b with

b = RealClass.new(...)

It would keep this reference (which allows full access to b) to itself.
When it wanted to give other objects a reference to b, it would give them

SafeProxy.new(b)

Which would ensure that the other classes could only access the safe
methods in b.

// Niklas


(Alan Chen) #6

Is your intent that some methods in object B will be callable by
"non-creators"? If not, could you simply hide the instantation of
object B inside object A?

···

On Fri, Jun 07, 2002 at 05:28:02AM +0900, Mathew Johnston wrote:

Hmm :slight_smile: What I’m trying to do is ensure that only the object which
created another object can call it’s methods. For example, object A
instantiates object B. In object B’s initialize method, I would set an
object variable (@creator), referencing the object that called .new. On
method calls, I would “raise ‘Method called by non-creator’ if [insert
method to get ref to caller object].id == @creator.id

Is there another way to do this?

Mat.


Alan Chen
Digikata LLC


(Paul Brannan) #7

Or, alternatively, use have objects A and B share a common object C (and
don’t let them hand a reference to C out to anyone).

Paul

···

On Sat, Jun 08, 2002 at 02:11:16AM +0900, Alan Chen wrote:

Is your intent that some methods in object B will be callable by
"non-creators"? If not, could you simply hide the instantation of
object B inside object A?