From: Takaaki T. <tt...@ja...> - 2001-08-18 01:19:06
|
At Fri, 17 Aug 2001 16:58:35 -0700, Kevin Smith <kev...@ho...> wrote: > > I've tried to implement the above class, but some problems are found. > > if we implement classes RBFL_Xxxx and RBFL_Yyyy, RBFL_Yyyy is a subclass > > of the class RBFL_Xxxx, we obtain the following class hierarchy. > > > > Fl_Xxxxx -------> RBFL_Xxxxx > > | > > | > > V > > Fl_Yyyyy -------> RBFL_Yyyyy > > That seems fine, as long as we don't need RBFL_Yyyyy to inherit from > RBLF_Xxxxx. I thought about this some, and couldn't think of a reason we > needed it. in current implementation, when we call the ruby method `do_callback' of the class `Fltk::Adjuster', `do_callback()' of the C++ class `RBFLWidget' is used. so the ruby inheritance is closely coupled with C++ inheritance. I will show you the simple example of this mechinism. now we assume that there are two C++ classes A and B, we make Ruby wrapper classes RA and RB, and use C symbols `rb_cRA' and `rb_cRB' for ruby classes `RA' and `RB' respectively. A and B is like: class A { A(){ ... }; func_a(){ ... }; }; class B : public A { B(): A(){ ... }; func_b(){ ... }; }; we can create the ruby classes like this: rb_cRA = rb_define_class("RA", rb_cObject); rb_define_sigleton_method(rb_cRA, "new", rb_a_new, 0); rb_define_method(rb_cRA, "func_a", rb_a_func_a, 0); rb_cRB = rb_define_class("RB", rb_cRA); rb_define_sigleton_method(rb_cRB, "new", rb_b_new, 0); rb_define_method(rb_cRB, "func_b", rb_b_func_b, 0); where `rb_a_new()', `rb_b_new()', `rb_a_func_a()' and `rb_b_func_b()' are defined like: VALUE rb_a_new(VALUE klass) { A *data = new A(); return Data_Wrap_Struct(klass, .... ,data); }; VALUE rb_b_new(VALUE klass) { B *data = new B(); return Data_Wrap_Struct(klass, ...., data); }; VALUE rb_a_func_a(VALUE self) { A *data; Data_Get_Struct(self, A, data); data->func_a(); return Qnil; }; VALUE rb_b_func_b(VALUE self) { B *data; Data_Get_Struct(self, B, data); data->func_b(); return Qnil; }; and if we run the following ruby code: b = RB.new b.func_a() the method `func_a' of the class RA is used since there is no such method in the RB. so the function `rb_a_func_a()' is called. the value of `self' represent the `b'. we can obtain the `data' as the object instantiated from the class A using Data_Get_Struct(), but `data' is the object instantiated from the class B. something like the cast is done here. of course, this is depend on the implementation. the advantage is that we don't need to implement all methods for each subclass. > Do we need our wrappers to inherit from each other? If not, I'd prefer to > avoid having parallel hierarchies. I'm very interested in your idea, but I'd like to use the mapping from C++ object to Ruby object using something like Hash again from the following reasons. - we'd like to avoid the multiple inheritance. - it is not recommended that ruby object is owned by the `RBFLXxxx'. - (I don't want to write all methods for each class.) but I want to think about this issue for a few days, since I think that it is the most important point of Ruby/Fltk. and I will try to find another design improving your idea. -- Takaaki Tateishi <tt...@ja...> |