Robert Klemme wrote:
> On 23.03.2008 16:15, Jeff Patterson wrote:
>> I'm writing a system simulator in ruby (think systemC). The snippet
>> below shows a typical invocation:
> 
> <snip/>
> 
>> 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.

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 :owner, :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.

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

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
-- 
Posted via http://www.ruby-forum.com/.