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.
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.
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? 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.
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
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.
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?
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?
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)
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.
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)
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.
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?
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
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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.