Paul Brannan <pbrannan / atdesk.com> writes:

> On Sun, Nov 02, 2003 at 06:43:14AM +0900, Shu-yu Guo wrote:
>> In 1.6, when writing an extension which required Data_Wrap_Struct, the
>> programmer would define the singleton method "new" to handle that. In 1.8, the
>> scheme seems to be to write an allocate function (to pass to
>> rb_define_alloc_func) then do the rest of the code in the intialize function.
>> Indeed, that's what Class#new does now.
>> 
>> So my question is, when writing extensions, is the "old" way of defining the
>> singleton method "new" deprecated? Are we to use the new allocate/initialize
>> way now?
>
> You can do this on 1.6:
>
>   inline VALUE ruby_16_new(int argc, VALUE * argv, VALUE klass)
>   {
>     VALUE obj = rb_funcall(klass, rb_intern("allocate"), 0);
>     rb_obj_call_init(obj, argc, argv);
>     return obj;
>   }
>
>   rb_define_singleton_method(klass, "allocate", allocate_func, -1);
>   rb_define_singleton_method(klass, "new", ruby_16_new, -1);
>   rb_define_method(klass.v, "initialize", initialize_func, -1);
>
> This allows you to divide your code into allocate/initialize similar to
> how you would on 1.8.

Or you can do this on 1.6 and 1.8:

  static VALUE foo_s_allocate(VALUE klass)
  {
    ......
  }

  static VALUE foo_initialize(int argc, VALUE *argv, VALUE self)
  {
    ......
  }

  #ifndef HAVE_RB_DEFINE_ALLOC_FUNC
  /* ruby 1.6 */
  static VALUE foo_s_new(int argc, VALUE * argv, VALUE klass)
  {
    VALUE obj = foo_s_allocate(klass);
    rb_obj_call_init(obj, argc, argv);
    return obj;
  }
  #endif

  void Init_foo()
  {
    ....
  #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
    /* ruby 1.8 */
    rb_define_alloc_func(klass, foo_s_allocate);
  #else
    /* ruby 1.6 */
    rb_define_singleton_method(klass, "new", foo_s_new, -1);
  #endif  
    rb_define_method(klass, "initialize", foo_initialize, -1);
    ....
  }

-- 
KUBO Takehiro
kubo / jiubao.org