Self / this question

When I do:

ab4435 = MyClassFoo.new(blah)

I want to get instance variable name 'ab4435' inside the class for use
in a methods.

I do this in itcl using uplevel by peeking at the calling stack frame
within the constructor and setting an instance variable mThis to the
string on the left of the = sign.

What's the ruby way to do this?

thanks,

Kape

···

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

When I do:

ab4435 = MyClassFoo.new(blah)

I want to get instance variable name 'ab4435' inside the class for use
in a methods.

...

What's the ruby way to do this?

I think most of us would discourage such opaque trickery, but if you
really Really REALLY need to, I think I would do something like:

Declare a method that takes a parameter of a symbol, passes the symbol
to the constructor, and uses the symbol to set an instance variable to
the resulting value with instance_variable_set. Then invoke it like
"make_foo :bar" to do the equivalent of "bar = MyClassFoo.new(:bar,
&any, Other::Arguments)".

How? Not gonna show you. Too much ugly code out there already.

-Dave

···

On Fri, Mar 7, 2014 at 3:51 PM, Kape Kape <lists@ruby-forum.com> wrote:

--
Dave Aronson, FREELANCE SOFTWARE DEVELOPER LOOKING FOR REMOTE CONTRACTS
(or temp jobs, or in/near Fairfax VA; see www.Codosaur.us for details);
see also www.PullRequestRoulette.com, Blog.Codosaur.us, www.Dare2XL.com

I'm more curious what you intend to do with this. There may be a more
ruby way of doing what you want rather than just making something work
the way it does in another language. What is the use case for this
sort of thing? When you have the ability to do what you want, what
does that get you?

I've found and been shown ever more some awesome ways of doing things
in ruby that my previous experience had me going in a different
direction.

···

On Fri, Mar 7, 2014 at 3:43 PM, Dave Aronson <ruby-talk.list.2.TRex@codosaur.us> wrote:

On Fri, Mar 7, 2014 at 3:51 PM, Kape Kape <lists@ruby-forum.com> wrote:

When I do:

ab4435 = MyClassFoo.new(blah)

I want to get instance variable name 'ab4435' inside the class for use
in a methods.

...

What's the ruby way to do this?

I think most of us would discourage such opaque trickery, but if you
really Really REALLY need to, I think I would do something like:

Declare a method that takes a parameter of a symbol, passes the symbol
to the constructor, and uses the symbol to set an instance variable to
the resulting value with instance_variable_set. Then invoke it like
"make_foo :bar" to do the equivalent of "bar = MyClassFoo.new(:bar,
&any, Other::Arguments)".

How? Not gonna show you. Too much ugly code out there already.

-Dave

--
Dave Aronson, FREELANCE SOFTWARE DEVELOPER LOOKING FOR REMOTE CONTRACTS
(or temp jobs, or in/near Fairfax VA; see www.Codosaur.us for details);
see also www.PullRequestRoulette.com, Blog.Codosaur.us, www.Dare2XL.com

I'm more curious what you intend to do with this. There may be a more
ruby way of doing what you want rather than just making something work
the way it does in another language. What is the use case for this
sort of thing? When you have the ability to do what you want, what
does that get you?

Isn't it obvious? :slight_smile: It gets you knowledge of the calling layer from an
instance perspective and it typically makes callback oriented code more
trivial. It makes the object self aware of its calling environment.

For abstraction purposes, when I create ab4355 for myself and that
object talks to a log file, the network, or some foreign callback
environment it can identify itself as such "built in". This is
sometimes far more important than whatever glamor the object might have
as a standalone, especially when you have 1000's of simple short lived
objects.

···

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

Dave Aronson wrote in post #1139187:

When I do:

ab4435 = MyClassFoo.new(blah)

I want to get instance variable name 'ab4435' inside the class for use
in a methods.

...

What's the ruby way to do this?

I think most of us would discourage such opaque trickery, but if you
really Really REALLY need to, I think I would do something like:

Declare a method that takes a parameter of a symbol, passes the symbol
to the constructor, and uses the symbol to set an instance variable to
the resulting value with instance_variable_set. Then invoke it like
"make_foo :bar" to do the equivalent of "bar = MyClassFoo.new(:bar,
&any, Other::Arguments)".

How? Not gonna show you. Too much ugly code out there already.

-Dave

I really, really need to :slight_smile:

Let me ask a slightly different question. Is the instance variable used
by the caller of new() considered to be of type 'symbol'?

I'm not trying to do trickery, I simply want the object to be able later
identify itself to the caller's environment with that name in a log
file.

thanks,

Kape

···

On Fri, Mar 7, 2014 at 3:51 PM, Kape Kape <lists@ruby-forum.com> wrote:

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

Kape Kape wrote in post #1139185:

I want to get instance variable name 'ab4435' inside the class for use
in a methods.

You can this with binding() object (ie. ruby Api: Binding
encapsulate the execution context at some particular place
in the code and retain this context for future use)

···

============
def ca(bind,name)
   c=(eval(name,bind)+1 rescue "unknown")
   puts "in call, #{name}=#{eval(name,bind)}"
   binding()
end

b=rand 1..111
p b
a=2

a= ca(binding(),"a")
ca(binding(),"b")
ca(binding(),"a")
ca(a,"c")

ruby a.rb

17
in call, a=2
in call, b=17
in call, a=#<Binding:0x26574f0>
in call, c=3

I do this in itcl using uplevel by peeking at the calling stack frame

I am not sure that work in tcl :

set a [doit ]

'a' is unknown at calling time of 'doit'

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

"caller" is a method that returns the call stack; "caller.first" would get a string with the file and line (and if you're lucky, method name) the current method was called from, colon-delimited. Does that help?

···

On Mar 7, 2014, at 11:16 PM, Kape Kape <lists@ruby-forum.com> wrote:

I'm not trying to do trickery, I simply want the object to be able later
identify itself to the caller's environment with that name in a log
file.

This concept sounds rather wrong to me. What is supposed to happen
when two variables reference the same object?

2.1.1 :001 > foo = "I'm foo"
=> "I'm foo"
2.1.1 :002 > bar = foo
=> "I'm foo"
2.1.1 :003 > foo.object_id
=> 84579520
2.1.1 :004 > bar.object_id
=> 84579520

It's the **same** object.
Should it identify itself as "foo" or "bar"???

It could not work.

Regards,
Marcus

···

Am 08.03.2014 05:07, schrieb Kape Kape:

I'm more curious what you intend to do with this. There may be a more
ruby way of doing what you want rather than just making something work
the way it does in another language. What is the use case for this
sort of thing? When you have the ability to do what you want, what
does that get you?

Isn't it obvious? :slight_smile: It gets you knowledge of the calling layer from an
instance perspective and it typically makes callback oriented code more
trivial. It makes the object self aware of its calling environment.

For abstraction purposes, when I create ab4355 for myself and that
object talks to a log file, the network, or some foreign callback
environment it can identify itself as such "built in". This is
sometimes far more important than whatever glamor the object might have
as a standalone, especially when you have 1000's of simple short lived
objects.

--
GitHub: stomar (Marcus Stollsteimer) · GitHub
PGP: 0x6B3A101A

Regis d'Aubarede wrote in post #1139242:

Kape Kape wrote in post #1139185:

I want to get instance variable name 'ab4435' inside the class for use
in a methods.

You can do this with binding() object (ie. ruby Api: Binding
encapsulate the execution context at some particular place
in the code and retain this context for future use)

============
def ca(bind,name)
   c=(eval(name,bind)+1 rescue "unknown")
   puts "in call, #{name}=#{eval(name,bind)}"
   binding()
end

b=rand 1..111
p b
a=2

a= ca(binding(),"a")
ca(binding(),"b")
ca(binding(),"a")
ca(a,"c")

ruby a.rb

17
in call, a=2
in call, b=17
in call, a=#<Binding:0x26574f0>
in call, c=3

I do this in itcl using uplevel by peeking at the calling stack frame

I am not sure that work in tcl :

set a [doit ]

'a' is unknown at calling time of 'doit'

Maybe it wasn't uplevel I think it was info level in tcl, haven't looked
at that code in years but:

set caller [info level [expr [info level] - 1]]

Can give you the caller's line, used in an itcl constructor this can be
used to determine the string which the creator of the object is calling
it.

···

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

Nope, didn't understand a bit of that, why it would be important to
do. If you do, super.

···

On Fri, Mar 7, 2014 at 10:07 PM, Kape Kape <lists@ruby-forum.com> wrote:

I'm more curious what you intend to do with this. There may be a more
ruby way of doing what you want rather than just making something work
the way it does in another language. What is the use case for this
sort of thing? When you have the ability to do what you want, what
does that get you?

Isn't it obvious? :slight_smile: It gets you knowledge of the calling layer from an
instance perspective and it typically makes callback oriented code more
trivial. It makes the object self aware of its calling environment.

For abstraction purposes, when I create ab4355 for myself and that
object talks to a log file, the network, or some foreign callback
environment it can identify itself as such "built in". This is
sometimes far more important than whatever glamor the object might have
as a standalone, especially when you have 1000's of simple short lived
objects.

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

> I'm more curious what you intend to do with this. There may be a more
> ruby way of doing what you want rather than just making something work
> the way it does in another language. What is the use case for this
> sort of thing? When you have the ability to do what you want, what
> does that get you?

Isn't it obvious? :slight_smile:

No, it isn't.

It gets you knowledge of the calling layer from an
instance perspective and it typically makes callback oriented code more
trivial. It makes the object self aware of its calling environment.

For abstraction purposes, when I create ab4355 for myself and that
object talks to a log file, the network, or some foreign callback
environment it can identify itself as such "built in". This is
sometimes far more important than whatever glamor the object might have
as a standalone, especially when you have 1000's of simple short lived
objects.

If you want to track object creation you could do something along these
lines:

class Tracker
  module CreationStackAccess
    attr_reader :__created__
  end

  def initialize
    @stacks = Hash.new {|h, k| k.each(&:freeze); k.freeze; h[k] = k}
  end

  def new(clazz, *a, &b)
    stack = @stacks[caller]

    clazz.new(*a, &b).tap do |obj|
      obj.instance_variable_set('@__created__', stack)
      obj.extend CreationStackAccess
    end
  end
end

class Foo
  def initialize
    yield 123 if block_given?
  end
end

$TRACKER = Tracker.new

f = $TRACKER.new Foo

p f.__created__

foos = 10.times.map { $TRACKER.new Foo }

foos.each do |f|
  printf "%10s %p\n", f.__created__.object_id, f.__created__
end

Of course you can also integrate that functionality into Class instances if
you find Foo.new_tracked or even Foo.new nicer than the method on another
instance. The main idea remains: you explicitly track creation of specific
"interesting" objects and record their creation call stack. The code
additionally stores only one instance per different call stack to keep the
memory overhead under control.

However, generally I'd say if objects need to be identifiable in some way
for logging purposes you should add fields that record information that you
reasonably want to log. Automatically tracking all creations of instances
is more like a debugging feature which should not be present in production
code because of the overhead. My two cents.

Cheers

robert

···

On Sat, Mar 8, 2014 at 5:07 AM, Kape Kape <lists@ruby-forum.com> wrote:

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

I'm ass-u-me'ing that the desired behavior is that it identify itself
with whatever name was used to create it. So if you do:

make_gladiator(:spartacus)
crixus = spartacus
crixus.identify

it says "I'm Spartacus!"

-Spartacus, er, I mean, Dave

···

On Sat, Mar 8, 2014 at 8:07 AM, <sto.mar@web.de> wrote:

It's the **same** object.
Should it identify itself as "foo" or "bar"???

--
Dave Aronson, FREELANCE SOFTWARE DEVELOPER LOOKING FOR REMOTE CONTRACTS
(or temp jobs, or in/near Fairfax VA; see www.Codosaur.us for details);
see also www.PullRequestRoulette.com, Blog.Codosaur.us, www.Dare2XL.com

Just because something is a (possibly) common practice in one language doesn't make it a good idea in another language. This reeks of bad design smell (in ruby) and should be avoided.

Every object in ruby already has their own identity. It's one of the basic tenants of object orientation. #object_id, #inspect, and others are all available for such purposes.

···

On Mar 8, 2014, at 16:40, Kape Kape <lists@ruby-forum.com> wrote:

Maybe it wasn't uplevel I think it was info level in tcl, haven't looked
at that code in years but:

set caller [info level [expr [info level] - 1]]

Can give you the caller's line, used in an itcl constructor this can be
used to determine the string which the creator of the object is calling
it.