From: Charles Mills Date: 2005-09-29T01:51:44+09:00 Subject: Re: delayed initialization with alloc_function Duncan Mac-Vicar Prett wrote: > Hello guys, I am wrapping a C++ library and after changing from define > singleton method "new" to alloc function and initialize, I ran into this > problem, imagine the classes are like those: > > class MyOtherClass > { > public: > MyOtherClass(int a, int b); > private: > int a; > int b; > } > > class MyClass > { > public: > MyClass(int a, int b); > MyOtherClass myFunc(int c); > private: > int a; > int b; > }; > > 1.- in alloc function, I have to create a MyClass object and wrap it with > Data_Wrap_Struct, but I cant create an object at that time, because I have no > constructor parameter until initialize (and I dont have a default constructor > either). How do I solve this? > 2.- If class MyClass func returns a MyOther class object, whats the best way > to wrap this?, I have even a function that returns a collection of > MyOtherClass objects, so I think I have to iterate trough it, and create a > ruby wrapped object not from scratch but wrapping the current object in the > collection, and then add all the ruby objects to a Ruby array, in this case, > whats the best way to wrap it? > > Thanks for the help guys! > > Duncan You have two options: 1) Don't use an alloc/initialize and instead override 'new'. This is simple, but it does not follow the ruby way, nor does it allow your class to be subclassed. 2) Make a dummy alloc function, then do all the work in initialize. (This is my preference.) Your alloc function would look like: VALUE my_alloc(VALUE klass) { return Data_Wrap_Struct(klass, NULL, NULL, NULL); } and your initialize function like: VALUE my_init(int argc, VALUE *argv, VALUE self) { MyOtherClass *p; /* handle args, create and initialize MyOtherClass instance */ RDATA(self)->dmark = my_mark_function; RDATA(self)->dfree = my_free_function; RDATA(self)->data = p; return self; } You also should check RDATA(self)->data != NULL in all your methods. This is easy though: #define GetMyOtherClass(obj, var) do { \ Data_Get_Struct(obj, MyOtherClass, var); \ if ((var) == NULL) rb_raise(rb_eFatal, "you never initialized me"); \ } while (0) You may also want to define a replace function (see array.c or string.c). --I am not much of a C++ programmer, so syntax may be wrong-- -Charlie