From: Charlie S. <cf...@in...> - 2006-01-17 18:46:38
|
I agree that you can get around this by defining static methods on the class, and its a good point that you could manually make them constructors. Here is how new is defined in the Ruby C source code: VALUE rb_class_new_instance(argc, argv, klass) int argc; VALUE *argv; VALUE klass; { VALUE obj; obj = rb_obj_alloc(klass); rb_obj_call_init(obj, argc, argv); return obj; } > then if you need extra new's, it could be like > > class Something > def self.new2(*a) obj = self.allocate; obj.initialize2(*a); obj end > def self.new3(*a) obj = self.allocate; obj.initialize3(*a); obj end > end > > The problem with the above is that the Ruby code has no way to get at the C initializer functions SWIG has produced. You'd have to change SWIG to expose these initializer functions to Ruby by registering them as singleton methods on the class. And once you've got that far, you might as well just do the whole job in SWIG so you don't have to have two files - one the C code and the other some Ruby wrapper class. So you'd have to change SWIG to: 1) Only generate one allocate method - there is no point in having multiple ones 2) Rename wrap_new_Foo_int methods to wrap_init_Foo_int methods. 3) Generate additional wrapper methods called wrap_new_Foo_int that do something like this: wrap_new_Foo_int {int argc, VALUE *argv) { VALUE self = rb_obj_alloc(klass); wrap_init_Foo_int(argc, argv, self); return self; } 4) Register these new methods as singleton_methods: rb_define_singleton_method(cFoo.klass, "new_from_int", VALUEFUNC(_wrap_init_Foo_int), -1) And that should do it. But once again, is this really necessary? The only thing it enables is the ability to rename constructor functions via the %rename directive. SWIG already let's you have multiple constructors with the same name since it supports method overloading. Thus in this case you can call Foo.new() or Foo.new(3) already. Do you really need to also have Foo.new_from_int(3)? My thoughts are no - its not worth bothering. Thanks, Charlie > where .allocate is the same but both .new and #initialize have parallel > renamings. This could be generated automatically: > > class Something > def self.constructor(suffix) > eval "def self.new#{name} (*a) > obj = self.allocate; obj.initialize#{name}(*a); obj end" > end > constructor "2" > constructor "3" > end > > note: .allocate should (ideally) produce a Ruby object that you cannot > crash Ruby with, but in this case I don't really know what to do. Maybe > it's fine to instead have .allocate be only safe as long as the first > methodcall on the allocated object is an initialize-compatible call ? > > _ _ __ ___ _____ ________ _____________ _____________________ ... > | Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju > | Freelance Digital Arts Engineer, Montréal QC Canada > > > |