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

On Fri, Mar 7, 2014 at 3:51 PM, Kape K. [email protected] 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

On Fri, Mar 7, 2014 at 3:43 PM, Dave A.
[email protected] wrote:

-Dave


Dave A., 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.

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.

Dave A. wrote in post #1139187:

On Fri, Mar 7, 2014 at 3:51 PM, Kape K. [email protected] 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

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

Am 08.03.2014 05:07, schrieb Kape K.:

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.

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

On Sat, Mar 8, 2014 at 8:07 AM, [email protected] wrote:

It’s the same object.
Should it identify itself as “foo” or “bar”???

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 Mar 7, 2014, at 11:16 PM, Kape K. [email protected] 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.

“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?

Kape K. 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’

On Mar 8, 2014, at 16:40, Kape K. [email protected] 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.

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.

Regis d’Aubarede wrote in post #1139242:

Kape K. 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.

On Fri, Mar 7, 2014 at 10:07 PM, Kape K. [email protected] wrote:

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/.

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

On Sat, Mar 8, 2014 at 5:07 AM, Kape K. [email protected] 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:

No, it isn’t.

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