On 11 Aug, GOTO Kentaro wrote: > Hi, > > In message "[ruby-talk:00626] Next misbehavior (sorry :-)" > on 99/08/11, clemens.hintze / alcatel.de <clemens.hintze / alcatel.de> writes: > >>Only `Object' and `Struct' instances seems to call `initialize'. > > Matz said that initialize is a "getleman's agreement". Because, in > some cases, it is too late to call initialize after the construction > of object. For example, an array must be allocate memory when > construction. Many predefined classes have such property. (sorry, I > know my explain is not enough but I can't do well). Oh! I understand you, IMHO ;-) I had the same problem with my class `Point' that I have coded in C for my tutorial. But I have found a workaround, that I think that it solve my problem. Better I show it to you, before it comes into the tutorial, and THEN, people tell me how stupid I was ;-) I try to code a class `Point' and later derive a class `Point3D' from it.... First the `Point#new' method: VALUE pt_point_s_new(argc, argv, klass) int argc; VALUE *argv, klass; { VALUE obj; obj = Data_Wrap_Struct(klass, mark_point, free, NULL); rb_obj_call_init(obj, argc, argv); return obj; } Then it follows `Point#initialize'... VALUE pt_point_init(argc, argv, self) int argc; VALUE *argv, self; { VALUE aX, aY; pt_RPoint *point; int args; if (DATA_PTR(self) == NULL) DATA_PTR(self) = ALLOC(pt_RPoint); args = rb_scan_args(argc, argv, "02", &aX, &aY); switch (args) { case 1: aY = INT2NUM(0); /* fall thru */ case 0: aX = INT2NUM(0); } if (!IS_A(aX, rb_cNumeric) || !IS_A(aY, rb_cNumeric)) rb_raise(rb_eTypeError, "wrong argument type: must be Numeric"); Data_Get_Struc(obj, pt_RPoint, point); point->x = aX; point->y = aY; return self; } So, I thought, I would not need a `Point3D#new' method, because I delay the memory allocation until the instance is initialized via `Point#initialize'! The nice side effect is, that I can let `Point3D#initialize' allocate the memory for the `Point3D' instance. The datatype `RPoint3D' is, of course, very similar to `RPoint' at the beginning. Enhancements come later in the struct. But have a look... VALUE pt3_point_init(argc, argv, self) int argc; VALUE *argv, self; { VALUE aZ; int args; if (DATA_PTR(self) == NULL) DATA_PTR(self) = ALLOC(pt3_RPoint3D); pt_point_init(MIN(argc, 2), argv, self); aZ = ((argc == 3) ? argv[2] : INT2NUM(0)); if (!IS_A(aZ, rb_cNumeric)) rb_raise(rb_eTypeError, "wrong argument type: must be Numeric"); RPOINT3D(self)->z = aZ; return self; } As you can see, I reuse the `Point#init' method via `pt_point_init'. And the same is true for all `pt_point_XXX' methods. And it also works well, if I would code `Point3D' using Ruby. But, of course, I have to call the `Point#initialize' method via `super' within from the `Point3D#initialize' method. Any objections? [Very especial good code deleted (but not forgotten ;-)...] I like your example (2) more than (1). I will chose it! Tkank you!!! [...] > It was requiested by me and some persons. Because we can't imagine a > `new' numeric. You and some persons are right, IMHO ;-) > > -- gotoken \cle