CORE - Object Instantiation and Location

I

Ilias Lazaridis

#ruby 1.9
class Person
def initialize(name)
@name = name
@where = "don't know" #
end

def report
print "\n", @name, " instantiated in: ", @where, "\n"
end
end

p = Person.new("Nancy")
p.report

-

What I'm looking for:

how can I detect WHERE the object was instantiated?

* module
* class
* file name
* line number
*
something like

def initialize(name)
@name = name
@where = self.execution.called_from # Object
@where = self.execution.file_name # String with filename

..
 
B

Bala TS

I think you can use class variable


like this
@@name = name
@@where = "don't know"

if you initialization then you can get like this way
=> Nancy ................ Don't knonw
 
I

Ilias Lazaridis

2011/5/26 Ilias Lazaridis <[email protected]>:





This seems to do what you need.

http://snippets.dzone.com/posts/show/2787

Yes, this seems to do it for file/line/method

That seems to contain the solution for the function name.

And this is the right documentation, but I could not find (within
Object and Kernel) the construct I'm looking for (accessing calling
Module or Object).

#ruby 1.9
class Person
def initialize(name)
@name = name
@where = self.invoked_from # returns Object
end
def report
print "\n", @name, " instantiated in: ", @where, "\n"
end
end

p = Person.new("Nancy")
p.report #=> Nancy instantiated in: main

Is there something like "self.invocation_from", or how could this be
implemented?

Note that this should work on object model, returning a "living"
object.

..
 
R

Ryan Davis

Is there something like "self.invocation_from", or how could this be
implemented?

Note that this should work on object model, returning a "living"
object.

BARRIER - Bad Design Smell
 
J

James Gray

[Note: parts of this message were removed to make it a legal post.]

BARRIER - Bad Design Smell

I laughed so hard!

Just to make it clear for those following along: this feature would violate
multiple principals of object oriented programming and just good design,
which is probably why there's not a big push for it.

James Edward Gray II
 
I

Ilias Lazaridis

C

Christopher Dicely

I laughed so hard!

Just to make it clear for those following along: =C2=A0this feature would= violate
multiple principals of object oriented programming and just good design,
which is probably why there's not a big push for it.

While that's true, lots of Ruby has lots of features that, by default,
expose functionality whose use would violate principals of object
oriented programming and good design. This is generally a good thing,
IMO, because such design principals are generalities and, as such,
usually have specific instances in practice where excessive devotion
to them is counterproductive. The power to ignore them is often a good
thing for a language to have.

And, really, a frequently requested feature by Ruby users (which I
think was implemented in at least one Gem for pre-1.9 ruby, don't know
if there is anything that provides it for 1.9) has been something to
the effect of Binding.of_caller that would return the binding of the
point from which the current method was called; if such a method
existed, Ilias request would seem to just be solved by:

Binding.of_caller.eval { self }
 
C

Christopher Dicely

While that's true, lots of Ruby has lots of features that, by default,
expose functionality whose use would violate principals of object
oriented programming and good design. This is generally a good thing,
IMO, because such design principals are generalities and, as such,
usually have specific instances in practice where excessive devotion
to them is counterproductive. The power to ignore them is often a good
thing for a language to have.

And, really, a frequently requested feature by Ruby users (which I
think was implemented in at least one Gem for pre-1.9 ruby, don't know
if there is anything that provides it for 1.9) has been something to
the effect of Binding.of_caller that would return the binding of the
point from which the current method was called; if such a method
existed, Ilias request would seem to just be solved by:

Binding.of_caller.eval { self }

Or, more likely:

Binding.of_caller.eval "self"
 
I

Ilias Lazaridis

Or, more likely:

 Binding.of_caller.eval "self"


http://extensions.rubyforge.org/rdoc/classes/Binding.html
http://extensions.rubyforge.org/rdoc/

Yes, this should work, but it seems to have some problems, too:

http://www.ruby-forum.com/topic/175402

-

There is another solution, which I like more:

https://github.com/Asher-/sender

found within the answer to this question:

http://stackoverflow.com/questions/2016696/getting-module-of-caller-in-ruby

-

But I try to achieve it without C-level extensions, only with the
build in (1.9) object-model / reflection / *documented* call-stack
tracing etc.

The question is:

How to achieve this in a "clean" way, without going to C-level?

..
 
I

Ilias Lazaridis

This one could lead to a solution, at least a temporal one.

I can retrieve from the Kernel.caller the call stack, and from there
the information <main>.

How can I user the string "<main>" or "<class:MyClass>" to retrieve
the actual object of main or MyClass?

for "class:MyClass'

obj = Kernel.const_get("MyClass") #=> returns object which represents
MyClass

for "main"?

How can I retrieve the "main" object?

..
 
J

Jesús Gabriel y Galán

for "class:MyClass'

obj =3D Kernel.const_get("MyClass") #=3D> returns object which represents
MyClass

for "main"?

How can I retrieve the "main" object?

If you are in the top level, then self is that object:

puts self
puts self.class

If not, here is one way:

class Test
def give_me_main
eval 'self', TOPLEVEL_BINDING
end
end

o =3D Test.new.give_me_main
puts o
puts o.class


Jesus.
 
R

Robert Klemme

[...]
for "class:MyClass'
obj =3D Kernel.const_get("MyClass") #=3D> returns object which represe= nts
MyClass
for "main"?
How can I retrieve the "main" object?
[...]
=C2=A0 =C2=A0 eval 'self', TOPLEVEL_BINDING
[...]

Very nice, this works fine!

The approach is broken because you will never properly track anonymous
objects. E.g.

class Bar; end

class Factory
def create
Bar.new
end
end


bar =3D Factory.new.create
# now our creator is gone

If you want to make this traceable you will keep significantly more
objects alive than without creation tracking.

I suggest you settle with file and line number which should be
sufficient in the general case to identify the source location. With
a bit of coding you can even make this very memory savvy so the
overhead is far less than if you keep hold on the creator instance.

Cheers

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
I

Ilias Lazaridis

[...] - (setting requirement "anonymous objects", suggesting
processing)

No need to suggest me requirements and processing.

My use-case is solved (I have no requirement for "anonymous objects").

Within this thread, there is a link to solution on C-level (sender),
but for now I don't need it.

If you know other *existent* libraries which address this issue,
please mention it.

..
 
R

Robert Klemme

[...] - (setting requirement "anonymous objects", suggesting
processing)

No need to suggest me requirements and processing.

Since you didn't post a requirement yourself (you asked for a
particular solution) I took the liberty to suggest one commonly seen
during debugging.
My use-case is solved (I have no requirement for "anonymous objects").

Glad to see your problem has been solved (whatever it is).

Cheers

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
I

Ilias Lazaridis

[...] - (setting requirement "anonymous objects", suggesting
processing)
No need to suggest me requirements and processing.

Since you didn't post a requirement yourself (you asked for a
particular solution) I took the liberty to suggest one commonly seen
during debugging.
[...]

You are right (subjecting the requirement).

I apologize!

-

Note to readers:

I've not verified the quality of this solution, but it seems to be the
cleanest implementation (for 1.9)

https://github.com/Asher-/sender

..
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top