Sytem hook for instance names?

J

Jeff Patterson

Is there a system hook that allows a method to get an instance's symbol
from its' object id?

i.e.

a=SomeObject.new
SomeSystemhook(a) => :a (or "a" I suppose)

For the curious, here's a rather long winded explanation of what I need.

I'm writing a system simulator in ruby (think systemC). The snippet
below shows a typical invocation:

class MySim
def initialize
#
# instantiate components
@g1=Buffer.new:)g1)
@a2=Adder.new:)a2)
@d1=Dflop.new:)d1)
@d2=Dflop.new:)d2)
@clk=Clk.new:)clk)
@p3=Probe.new("d2Q") #trace d2's Q output
@d2[:Q].bind(@p3[:In])
..

# make connections
#note:
#the component master class defines:
# def [](name)
# return (@outputs+@inputs).find{|pin| name == pin.name}
# end
# so @g[:Out] returns a reference to its output pin object

@g1[:Out].bind(@a2[:I2]) # g1's Out pin -> a2's I2 pin
@d1[:Q].bind(@a2[:I1]) # etc
@clk.bind(@d1[:Clk])
..
end

def run # required call back routine for simulator engine
#control code goes here
@d1[:Rst]=set(true)
@d2[:Rst].set(true)
yield(1) # advance the simulation 1 clock period

@g1[:In].set(0.001)
@d1[:Rst].set(false)
@d2[:Rst].set(false)
yield(1000) #advance 1000 cycles
end
end

#run the simulation
sim=Simulation.new(MySim.new)
sim.run

Notice that the Sim object (with all off its components) is passed to
the Simulation engine (sim) for execution. The Simulation engine uses
Kernel#ObjectSpace to find and schedule objects it needs to manage. For
efficiency it flattens the netlist and extracts only the input pins and
clocked output pins it needs to manage. But for messaging, netlisting
etc, I want the sim engine to know the _name_ of the pins parent (as
opposed to its object_id) and I would also like to obviate the need to
redundantly pass the component's symbol name to its constructor. i.e.

instead of
@d1 = Dflop.new:)d1)

I want to be able to do:

@d1=Dflop.new

and then when the sim engine needs a human readable component name, it
somehow gets it from a system hook based on the object id.


Any help?

Jeff
 
B

botp

Is there a system hook that allows a method to get an instance's symbol from its' object id?

i do not understand what you mean by instance symbol but you can refer
fr an id back to the actual object if you want to. so but how about,

irb(main):021:0> a="testing"
=> "testing"
irb(main):022:0> x=a.object_id
=> -606066648
irb(main):023:0> ObjectSpace._id2ref(x)
=> "testing"
irb(main):024:0> ObjectSpace._id2ref(x).upcase!
=> "TESTING"
irb(main):025:0> a
=> "TESTING"
irb(main):026:0> b=Class.new
=> #<Class:0xb7bf9214>
irb(main):027:0> y=b.object_id
=> -606090998
irb(main):028:0> ObjectSpace._id2ref(y)
=> #<Class:0xb7bf9214>
irb(main):029:0> ObjectSpace._id2ref(y).class_eval "def hello; 'hello'; end"
=> nil
irb(main):031:0> b.new.hello
=> "hello"

hth.
kind regards -botp
 
M

Mark Bush

Jeff said:
Is there a system hook that allows a method to get an instance's symbol
from its' object id?

i.e.

a=SomeObject.new
SomeSystemhook(a) => :a (or "a" I suppose)

The problem is that the variable is not the object, just a pointer to
it. And there can be multiple variables pointing to the object. So:

a = SomeObject.new
b = a

Now "a" and "b" both point to the same object. How would you choose
between returning :a and :b?

If you don't mind, then for instance variables you can do something
like:

def get_instance_variable_symbol_for_object v
instance_variables.each do |var|
if value = instance_variable_get(var)
return var if value.object_id.eql?(v.object_id)
end
end
end

Untested.
 
R

Robert Klemme

The problem is that the variable is not the object, just a pointer to
it. And there can be multiple variables pointing to the object. So:

a = SomeObject.new
b = a

Now "a" and "b" both point to the same object. How would you choose
between returning :a and :b?

Plus, what would you do in this case?

a=[SomeClass.new]

Basically it makes no sense...

Cheers

robert
 
R

Robert Klemme

Is there a system hook that allows a method to get an instance's symbol
from its' object id?

i.e.

a=SomeObject.new
SomeSystemhook(a) => :a (or "a" I suppose)

For the curious, here's a rather long winded explanation of what I need.

I'm writing a system simulator in ruby (think systemC). The snippet
below shows a typical invocation:

Notice that the Sim object (with all off its components) is passed to
the Simulation engine (sim) for execution. The Simulation engine uses
Kernel#ObjectSpace to find and schedule objects it needs to manage.

IMHO that is bad design. The Sim instance needs to know about all
objects that belong to it. You should do that within your application
and not traverse all objects (of some kind). That is not very efficient
and has some problems of its own (threads, multiple Sim instances etc.).
For
efficiency it flattens the netlist and extracts only the input pins and
clocked output pins it needs to manage. But for messaging, netlisting
etc, I want the sim engine to know the _name_ of the pins parent (as
opposed to its object_id) and I would also like to obviate the need to
redundantly pass the component's symbol name to its constructor. i.e.

instead of
@d1 = Dflop.new:)d1)

I want to be able to do:

@d1=Dflop.new

That's easily solved:

Base = Struct.new :eek:wner, :name

class Sim
def initialize
@elements = {}
end

def create(name,cl,*args,&b)
x = cl.new(*args,&b)
x.owner = self
x.name = name
@elements[name] = x
end

# or

def create2(name)
x = yield
x.owner = self
x.name = name
@elements[name] = x
end

def some_other_method
create :d1, Dflop
create2:)d1) { Dflop.new }
end
end
and then when the sim engine needs a human readable component name, it
somehow gets it from a system hook based on the object id.
Any help?

Yes, do this yourself. As has been pointed out, there are various
issues with the concept of "the name of an instance" notably that every
object can have any number (including zero) references pointing to it.

Kind regards

robert
 
M

Mark Bush

Robert said:
Plus, what would you do in this case?

a=[SomeClass.new]

Actually, in this case it's not so bad. The variable "a" refers to the
array (so you're not interested in the array contents) so you can use
similar methods on local variables to get it's name, then do:

eval var

on each local variable to see if the object returned is your original
one, just not easily in a method as local variables are now in a
different scope, albeit the scope of the caller (and being very, very
careful about exceptions and side effects). What really made me cringe
was:

a = nil

Now what?

That's when I went and opened a bottle of wine and watched a movie.

I agree 100% though that the real issue here is that Jeff wants the name
of an object to be an attribute and the best way to do that is to, well,
make the name an attribute.
 
M

Marc Heiler

As has been pointed out, there are various
issues with the concept of "the name of an instance" notably that every
object can have any number (including zero) references pointing to it.


That may be correct, but "a number-based system" can be beautiful. Any
LPC MUD should convince a sceptic that finding all the various objects
in the system based on their id (or cloned instance in case of the LPC
world) is nice to have.

For me it seems visually appealing to have all the various objects
floating around in one's mind - with their id tag attached to them
directly :)
 
J

Jeff Patterson

Robert said:
it. And there can be multiple variables pointing to the object. So:

a = SomeObject.new
b = a

Now "a" and "b" both point to the same object. How would you choose
between returning :a and :b?

Plus, what would you do in this case?

a=[SomeClass.new]

Basically it makes no sense...

Cheers

robert

Thanks for the response. It seems to me that both of these issue could
be covered by simply returning an array of the symbol names which point
to a object or [] if an object has no name associated with it.
 
J

Jeff Patterson

Robert said:
IMHO that is bad design. The Sim instance needs to know about all
objects that belong to it.

Hmmm. Certainly the Sim instance does contain all of the component
objects and their connections. The actual simulation logic though (i.e.
the dynamic manipulations of those objects in simulation time) IMHO
needs to be relegated to a black box (the Simulation engine) that the
user doesn't need to concern himself with. The Sim object is the netlist
that the user must write for each system model so it's syntax needs to
be a clean as possible.

As for efficiency:
1) it is probably (hopefully?) more efficient to use the system hook
than to write a method to do the same thing but which confines the
traversal to the Sim object passed to the engine, although I agree that
the latter would be desirable from a purist OO standpoint.

2) efficiency isn't important here since it only occurs once, before the
start of the simulation.
You should do that within your application
and not traverse all objects (of some kind). That is not very efficient
and has some problems of its own (threads, multiple Sim instances etc.).

That's a good point. I suppose its possible that there be more than one
sim instance (although the thought hadn't occurred to me) whereby the
user wants to model cooperation between two systems. I may have to write
that method after all :>)
I want to be able to do:

@d1=Dflop.new

That's easily solved:

Base = Struct.new :eek:wner, :name

class Sim
def initialize
@elements = {}
end

def create(name,cl,*args,&b)
x = cl.new(*args,&b)
x.owner = self
x.name = name
@elements[name] = x
end

# or

def create2(name)
x = yield
x.owner = self
x.name = name
@elements[name] = x
end

def some_other_method
create :d1, Dflop
create2:)d1) { Dflop.new }
end
end

I like the first approach (Thanks!) But I don't see where you've use the
Base struct you created. I'm new to ruby (but not to Structs) so I'll
have to do some digging here.
Yes, do this yourself.
As has been pointed out, there are various
issues with the concept of "the name of an instance" notably that every
object can have any number (including zero) references pointing to it.

Sorry if I'm being dense here but I don't see the issue. Simply
returning some sort of Enumeration (array, hash, linked list etc) with
all or none would do the trick. If it's reasonable for the kernel to
associate a unique id# with an object (and it is :>) then its also
reasonable to associate a name (or names) upon assignment of that object
to an instance variable. Further, such an association _must_ already
exist (otherwise when I write @d1.some_method, the kernel wouldn't know
which object I'm referencing). If the kernel has a hash of references,
why can't we access it?

Programmers have fought C's (and therefore C++'s) lack of introspection
(reflection) since the DoT. With a compiled language it is impossible
(or at least very very hard) to do these kinds of things. It seems to me
that Ruby should fully capitalize at every turn on the advantages
interpretation brings

Thank you kindly for your suggestions
Jeff
 
J

Jeff Patterson

Mark said:
Robert said:
Plus, what would you do in this case?

a=[SomeClass.new]

Actually, in this case it's not so bad. The variable "a" refers to the
array (so you're not interested in the array contents) so you can use
similar methods on local variables to get it's name, then do:

eval var

on each local variable to see if the object returned is your original
one, just not easily in a method as local variables are now in a
different scope, albeit the scope of the caller (and being very, very
careful about exceptions and side effects). What really made me cringe
was:

a = nil

Since nil is an instance of NilClass, I suppose
MyProposedSystemHook(nil) would return [:a,...any other variable
_assigned_ to nil]
<I agree 100% though that the real issue here is that Jeff wants the name
of an object to be an attribute

No! (unless you meant Kernel attribute, which it already is, at least
indirectly). The symbol name cannot belong to the object because rvalues
can not know about lvalues at instantiation. Howeevr, the kernel owns
both and so can manage associations between them!
 
M

Mark Bush

Jeff said:
Thanks for the response. It seems to me that both of these issue could
be covered by simply returning an array of the symbol names which point
to a object or [] if an object has no name associated with it.

Potentially. You could fudge it with something like (in Object):

def get_variable_names context, locals, instances
names = []
(locals + instances + global_variables).each do |var_name|
if value = eval(var_name, context)
names << var_name if value.object_id.eql?(object_id)
end
end
names
end

and use it like:

foo.get_variable_names binding, local_variables, instance_variables

You need to pass in local and instance variable names because the
context of the method call is different to the context of the caller and
the caller's binding is needed to evaluate these. There may be a way of
getting the callers context which would give you these, but I don't know
how offhand.

This is not a clean solution, and if Ruby doesn't give you the caller's
context then the only other solution I can see is to carry the
information around with the object.
 
M

Mark Bush

Jeff said:
which object I'm referencing). If the kernel has a hash of references,
why can't we access it?

Not any use to you at all, but in Smalltalk, variables are just keys in
a namespace and namespaces are dictionaries (hashes). It would be nice
if the same were so in Ruby but, AFAIK, variable mappings are held
internally to the Ruby interpreter and not exposed. If they were, then
this would be much easier...
 
T

Todd Benson

Robert said:
On 23.03.2008 19:30, Mark Bush wrote:
it. And there can be multiple variables pointing to the object. So:

a = SomeObject.new
b = a

Now "a" and "b" both point to the same object. How would you choose
between returning :a and :b?

Plus, what would you do in this case?

a=[SomeClass.new]

Basically it makes no sense...

Cheers

robert

Thanks for the response. It seems to me that both of these issue could
be covered by simply returning an array of the symbol names which point
to a object or [] if an object has no name associated with it.

I've thought about this, but objects are created and collected on the
fly. In other words, the information wouldn't do you much good. For
example, every time you do #each, a block is momentarily created. You
always have an object that has zero or more actual variable "names".

Is it possible to grab all the references at one point in time? Yes.
But, would it be useful or reliable? I'm not so sure. Maybe if you
froze everything :)

Todd
 
R

Rick DeNatale

Not any use to you at all, but in Smalltalk, variables are just keys in
a namespace and namespaces are dictionaries (hashes).

Not in general, they aren't.

Global variables, Pool Variables, and IIRC Class Variables are bound
through associations in Smalltalk dictionaries (although this might be
implementation dependent, and perhaps historical). Instance variables,
parameters, method and block temporaries are not.
 
R

Robert Klemme

Hmmm. Certainly the Sim instance does contain all of the component
objects and their connections. The actual simulation logic though (i.e.
the dynamic manipulations of those objects in simulation time) IMHO
needs to be relegated to a black box (the Simulation engine) that the
user doesn't need to concern himself with.

And? There is no issue making the simulation a black box. But since
you design the app you are free to design the interaction between the
simulator and the simulation data.
The Sim object is the netlist
that the user must write for each system model so it's syntax needs to
be a clean as possible.

That can still be achieved, see my example.
As for efficiency:
1) it is probably (hopefully?) more efficient to use the system hook
than to write a method to do the same thing but which confines the
traversal to the Sim object passed to the engine, although I agree that
the latter would be desirable from a purist OO standpoint.

2) efficiency isn't important here since it only occurs once, before the
start of the simulation.
You should do that within your application
and not traverse all objects (of some kind). That is not very efficient
and has some problems of its own (threads, multiple Sim instances etc.).

That's a good point. I suppose its possible that there be more than one
sim instance (although the thought hadn't occurred to me) whereby the
user wants to model cooperation between two systems. I may have to write
that method after all :>)
I want to be able to do:

@d1=Dflop.new
That's easily solved:

Base = Struct.new :eek:wner, :name

class Sim
def initialize
@elements = {}
end

def create(name,cl,*args,&b)
x = cl.new(*args,&b)
x.owner = self
x.name = name
@elements[name] = x
end

# or

def create2(name)
x = yield
x.owner = self
x.name = name
@elements[name] = x
end

def some_other_method
create :d1, Dflop
create2:)d1) { Dflop.new }
end
end

I like the first approach (Thanks!) But I don't see where you've use the
Base struct you created. I'm new to ruby (but not to Structs) so I'll
have to do some digging here.

Your specific classes would of course have to inherit from Base.
Alternatively you could define a module with both attribute accessors if
you want to use inheritance for something else.
Sorry if I'm being dense here but I don't see the issue. Simply
returning some sort of Enumeration (array, hash, linked list etc) with
all or none would do the trick.

There are still issues: How then would you know which one is the one you
wanted? And: what do you do about incomplete lists (i.e. instances
referenced from Hash, Array, extension code etc.)?
If it's reasonable for the kernel to
associate a unique id# with an object (and it is :>) then its also
reasonable to associate a name (or names) upon assignment of that object
to an instance variable.

IMHO no. Reason is that the overhead is significant. While you need
the object id for various things (GC bookkeeping comes to mind) you do
not need the names of all variables that refer an instance.
Further, such an association _must_ already
exist (otherwise when I write @d1.some_method, the kernel wouldn't know
which object I'm referencing). If the kernel has a hash of references,
why can't we access it?

No, the information is not there: This is a _directed_ relationship,
i.e. you can get from context and symbol to the instance but not back.
Programmers have fought C's (and therefore C++'s) lack of introspection
(reflection) since the DoT. With a compiled language it is impossible
(or at least very very hard) to do these kinds of things. It seems to me
that Ruby should fully capitalize at every turn on the advantages
interpretation brings

As always it's a tradeoff. Storing the kind of information in the
interpreter is a) error prone (there are some references that do not
have a symbol, i.e. inside an Array or in an extension), b) would place
the burden on *all* applications not only those that really need it and
c) can be easily built when needed (see my example). So the weight
comes down on the "don't do" side.

Cheers

robert
 

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,989
Messages
2,570,207
Members
46,783
Latest member
RickeyDort

Latest Threads

Top