CORE - Object Instantiation and Location

  • Follow


#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

..

--
http://lazaridis.com
0
Reply ilias (783) 5/26/2011 8:23:34 AM

2011/5/26 Ilias Lazaridis <ilias@lazaridis.com>:
>
> What I'm looking for:
>
> how can I detect WHERE the object was instantiated?

This seems to do what you need.

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

See also here:

http://www.ruby-doc.org/core/classes/Kernel.html#M001397

-- 
Roger Braun
rbraun.net | humoralpathologie.de

0
Reply roger2199 (12) 5/26/2011 10:31:10 AM


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

-- 
Posted via http://www.ruby-forum.com/.

0
Reply bdeveloper01 (9) 5/26/2011 10:34:30 AM

On 26 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 13:31, Roger Braun <ro...@rogerbraun.=
net> wrote:
> 2011/5/26 Ilias Lazaridis <il...@lazaridis.com>:
>
>
>
> > What I'm looking for:
>
> > how can I detect WHERE the object was instantiated?
>
> This seems to do what you need.
>
> http://snippets.dzone.com/posts/show/2787

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

> See also here:
>
> http://www.ruby-doc.org/core/classes/Kernel.html#M001397

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 =3D name
    @where =3D self.invoked_from # returns Object
  end
  def report
    print "\n", @name, " instantiated in: ", @where, "\n"
  end
end

p =3D Person.new("Nancy")
p.report #=3D> 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.

..

--
http://lazaridis.com
0
Reply ilias (783) 5/26/2011 7:54:19 PM

On May 26, 2011, at 12:55 , Ilias Lazaridis wrote:

> 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


0
Reply ryand-ruby (1309) 5/26/2011 8:53:29 PM

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

On Thu, May 26, 2011 at 3:53 PM, Ryan Davis <ryand-ruby@zenspider.com>wrote:

>
> On May 26, 2011, at 12:55 , Ilias Lazaridis wrote:
>
> > 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
>

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

0
Reply james223 (91) 5/26/2011 9:35:44 PM

On 26 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 13:31, Roger Braun <ro...@rogerbraun.=
net> wrote:
> 2011/5/26 Ilias Lazaridis <il...@lazaridis.com>:
>
>
>
> > What I'm looking for:
>
> > how can I detect WHERE the object was instantiated?
>
> This seems to do what you need.
>
> http://snippets.dzone.com/posts/show/2787
>
> See also here:
>
> http://www.ruby-doc.org/core/classes/Kernel.html#M001397

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?

..

--
http://lazaridis.com
0
Reply ilias (783) 5/27/2011 4:51:18 AM

On Thu, May 26, 2011 at 2:35 PM, James Gray <james@graysoftinc.com> wrote:
> On Thu, May 26, 2011 at 3:53 PM, Ryan Davis <ryand-ruby@zenspider.com>wro=
te:
>
>>
>> On May 26, 2011, at 12:55 , Ilias Lazaridis wrote:
>>
>> > 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
>>
>
> 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 }

0
Reply cmdicely (196) 5/27/2011 2:47:16 PM

On Fri, May 27, 2011 at 7:46 AM, Christopher Dicely <cmdicely@gmail.com> wr=
ote:
> On Thu, May 26, 2011 at 2:35 PM, James Gray <james@graysoftinc.com> wrote=
:
>> On Thu, May 26, 2011 at 3:53 PM, Ryan Davis <ryand-ruby@zenspider.com>wr=
ote:
>>
>>>
>>> On May 26, 2011, at 12:55 , Ilias Lazaridis wrote:
>>>
>>> > 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
>>>
>>
>> I laughed so hard!
>>
>> Just to make it clear for those following along: =C2=A0this feature woul=
d 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 }

Or, more likely:

 Binding.of_caller.eval "self"

0
Reply cmdicely (196) 5/27/2011 2:54:28 PM

On 27 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 17:54, Christopher Dicely <cmdic...@g=
mail.com> wrote:
> On Fri, May 27, 2011 at 7:46 AM, Christopher Dicely <cmdic...@gmail.com> =
[...]

> > 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:
>
> =C2=A0Binding.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?

..

--
http://lazaridis.com
0
Reply ilias (783) 5/29/2011 8:07:49 PM

On 27 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 07:51, Ilias Lazaridis <il...@lazarid=
is.com> wrote:
> On 26 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 13:31, Roger Braun <ro...@rogerbrau=
n.net> wrote:
>
> > 2011/5/26 Ilias Lazaridis <il...@lazaridis.com>:
>
> > > What I'm looking for:
>
> > > how can I detect WHERE the object was instantiated?
>
> > This seems to do what you need.
>
> >http://snippets.dzone.com/posts/show/2787
>
> > See also here:
>
> >http://www.ruby-doc.org/core/classes/Kernel.html#M001397
>
> 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 =3D Kernel.const_get("MyClass") #=3D> returns object which represents
MyClass

for "main"?

How can I retrieve the "main" object?

..

--
http://lazaridis.com

0
Reply ilias (783) 5/30/2011 7:54:18 AM

On Mon, May 30, 2011 at 9:55 AM, Ilias Lazaridis <ilias@lazaridis.com> wrot=
e:
> On 27 =CC=DC=FA=EF=F2, 07:51, Ilias Lazaridis <il...@lazaridis.com> wrote=
:
>> On 26 =CC=DC=FA=EF=F2, 13:31, Roger Braun <ro...@rogerbraun.net> wrote:
>>
>> > 2011/5/26 Ilias Lazaridis <il...@lazaridis.com>:
>>
>> > > What I'm looking for:
>>
>> > > how can I detect WHERE the object was instantiated?
>>
>> > This seems to do what you need.
>>
>> >http://snippets.dzone.com/posts/show/2787
>>
>> > See also here:
>>
>> >http://www.ruby-doc.org/core/classes/Kernel.html#M001397
>>
>> 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 =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.

0
Reply jgabrielygalan (544) 5/30/2011 8:06:59 AM

On 30 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 11:06, Jes=C3=BAs Gabriel y Gal=C3=A1=
n <jgabrielyga...@gmail.com>
wrote:
> On Mon, May 30, 2011 at 9:55 AM, Ilias Lazaridis <il...@lazaridis.com> wr=
ote:
[...]

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

Very nice, this works fine!

..

--
http://lazaridis.com
0
Reply ilias (783) 5/30/2011 9:03:12 AM

On Mon, May 30, 2011 at 11:05 AM, Ilias Lazaridis <ilias@lazaridis.com> wro=
te:
> On 30 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 11:06, Jes=C3=BAs Gabriel y Gal=C3=
=A1n <jgabrielyga...@gmail.com>
> wrote:
>> On Mon, May 30, 2011 at 9:55 AM, Ilias Lazaridis <il...@lazaridis.com> w=
rote:
> [...]
>
>> > 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/

0
Reply shortcutter (5780) 5/30/2011 3:00:12 PM

On 30 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 18:00, Robert Klemme <shortcut...@goo=
glemail.com> wrote:
[...] - (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.

..

--
http://lazaridis.com
0
Reply ilias (783) 5/31/2011 1:38:43 AM

On Tue, May 31, 2011 at 3:40 AM, Ilias Lazaridis <ilias@lazaridis.com> wrot=
e:
> On 30 =CC=DC=FA=EF=F2, 18:00, Robert Klemme <shortcut...@googlemail.com> =
wrote:
> [...] - (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/

0
Reply shortcutter (5780) 5/31/2011 8:28:02 AM

On 31 =CE=9C=CE=AC=CF=8A=CE=BF=CF=82, 11:28, Robert Klemme <shortcut...@goo=
glemail.com> wrote:
> On Tue, May 31, 2011 at 3:40 AM, Ilias Lazaridis <il...@lazaridis.com> wr=
ote:
> > On 30 =C3=8C=C3=9C=C3=BA=C3=AF=C3=B2, 18:00, Robert Klemme <shortcut...=
@googlemail.com> wrote:
> > [...] - (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

..

--
http://lazaridis.com
0
Reply ilias (783) 5/31/2011 1:01:52 PM

16 Replies
29 Views

(page loaded in 0.163 seconds)


Reply: