user2753200
user2753200

Reputation: 11

How to get the caller object name in ruby?

Frequently, the same method X gets called from different objects A, B, C. Is it possible to get a name of the caller object(A, B, C) from inside method X

eg :

class Sample
  def method
    # what needs to be done here?
  end
end

n1 = Sample.new
n2 = Sample.new

n1.method #=> expected output is to print n1
n2.method #=> expected output is to print n2

Upvotes: 1

Views: 2708

Answers (4)

undur_gongor
undur_gongor

Reputation: 15954

As others said, working with the object_id directly is most probably the much better approach.

Anyway, something along this line might work in your case:

class Sample
  def method(&b)
    eval("local_variables.select {|v| eval(v.to_s).object_id == #{object_id}}", 
         b.binding)
  end
end

n1 = Sample.new
n2 = Sample.new
n3 = n2

p n1.method {}         #=> [:n1]
p n2.method {}         #=> [:n2, :n3]
p Sample.new.method {} #=> []

It returns all (local) variables in the current scope referencing the callee object. If each of your objects is referenced by exactly one variable, this might be what you are looking for.

Suggested by Neil Slater: you can also use the gem binding_of_caller to simplify transferring the binding:

require 'binding_of_caller'

class Sample
  def method
    binding.of_caller(1).eval(
      "local_variables.select {|v| eval(v.to_s).object_id == #{object_id}}"
    )
  end
end

n1 = Sample.new
n2 = Sample.new
n3 = n2

p n1.method         #=> [:n1]
p n2.method         #=> [:n2, :n3]
p Sample.new.method #=> []

(tested with version 0.7.2 of the gem).

Upvotes: 4

Srikanth Jeeva
Srikanth Jeeva

Reputation: 3011

Just returning self should work,

Here is an example:

class Sample
  attr_accessor :name
  def method
    puts self  
    puts self.name  
  end
end

n1 = Sample.new
n1.name = "Bangalore"
n2 = Sample.new
n2.name = "Chennai"


n1.method #=> expected output is to print n1
n2.method #=> expected output is to print n2


-------
Output: 
#<Sample:0x7f492f62c030> # n1 object
Bangalore # n1.name 
#<Sample:0x7f492f62bec8> # n2 object
Chennai #n2.name

Upvotes: 0

7stud
7stud

Reputation: 48599

Any object can be identified by its object_id:

class Sample
  def method
    puts self.object_id
  end
end

n1 = Sample.new
n2 = Sample.new

puts n1.object_id
n1.method

puts n2.object_id
n2.method

--output:--
2152302060
2152302060
2152302040
2152302040

Variable names...not so much.

Upvotes: 3

Stefan
Stefan

Reputation: 114158

No, this doesn't work. Imaging the following:

n1 = Sample.new
n2 = n1

n2.method #=> ambiguous, both n1 and n2 would be valid

You could assign a name to your instances instead:

class Sample
  attr_accessor :name
end

n1 = Sample.new
n1.name = :n1

n2 = Sample.new
n2.name = :n2


n1.name #=> :n1
n2.name #=> :n2

Upvotes: 5

Related Questions