From: Lyle Johnson Date: 2001-08-08T13:35:29+09:00 Subject: [ruby-talk:19344] Re: Virtual list > Ah, see, the issue is that the Ruby objects won't exist to put into an > array. I need kind of a "virtual" array that will create the Ruby > objects on the fly from the C++ objects in the C++ list, when the Ruby > array is accessed. Also, when a new Ruby object is placed into the > array, the C++ class needs to be pulled out (check the Ruby class of the > object, of course) which would mean something like > > obj.attrs.add (AMAttribute.new ("type", "data", "etc")) > > would create an instance of the C++ class obj_attr (wrapped in the class > AMAttribute in Ruby), and pass that to the attrs object, which would > basically take the obj_attr pointer from the AMAttribute instance, and > call the following C++ code: > > obj->attrs.add (obj_attr_instance); > > The each member function of the attrs class (in Ruby) would call C++ > code that would loop thru all the elements in the C++ list, construct > the Ruby wrapper for the class, and call the yield'ed function on them. It sounds like your C++ extension module needs to define at least the following basic classes: AMObject AMAttribute AMContainer as well as (maybe) these list classes: class AMAttributeList { protected: std::list _attributes; public: AMAttributeList(std::list& attributes) : _attributes(attributes) {} void add(obj_attr *attribute) { _attributes.add(attribute); } // and whatever else is required }; class AMContainerList { protected: std::list _containers; public: AMContainerList(std::list& containers) : _containers(containers) {} void add(container *c) { _containers.add(c); } // and whatever else is required }; When the Ruby code calls your AMObject's "attrs" accessor method, it should return a reference to a wrapped AMAttributeList; when Ruby code calls your "containers" method (or whatever you decide to call it), AMObject should return a reference to a wrapped AMContainerList. Now, as for the interfaces for these two new list classes, you should make them as similar to Ruby's built-in arrays as you can ;) At a minimum, it looks like you want to include an "each" method and mix in the "Enumerable" module. Normal Ruby arrays also provide indexed access using the "[]" and "[]=" methods, but if your underlying STL container is std::list<> this may not be an option (at least, not an efficient option). Hope this helps, Lyle