在Ruby C擴展中,我看到了class costructor的奇怪行爲。
參見一個例子:我們有一個類Foo
是一個C擴展和類Bar
從Foo
繼承:Ruby C擴展中的構造函數的奇怪行爲
extconf.rb
# extconf.rb
require 'mkmf'
create_makefile('foo/foo')
foo.c的
// foo.c
#include "ruby.h"
#include <stdio.h>
VALUE
foo_new (VALUE class)
{
printf ("foo_new\n");
int *ptr;
VALUE tdata = Data_Wrap_Struct (class, 0, 0, ptr);
rb_obj_call_init (tdata, 0, 0);
return tdata;
}
VALUE
foo_init (VALUE self)
{
printf ("foo_init\n");
return self;
}
VALUE
foo_plus_one (VALUE self, VALUE x)
{
printf ("foo_plus_one\n");
return INT2FIX (FIX2INT (x) + 1);
}
void
Init_foo()
{
VALUE foo = rb_define_class ("Foo", rb_cObject);
rb_define_singleton_method (foo, "new", foo_new, 0);
rb_define_method (foo, "initialize", foo_init, 0);
rb_define_method (foo, "plus_one", foo_plus_one, 1);
}
bar.rb
# bar.rb
require './foo'
class Bar < Foo
end
好吧,讓我們看到奇怪的東西...
在這種情況下都去確定:
x = Bar.new
我們得到了2個打印:foo_new
和foo_init
。
好啊好啊,但如果我們改變這樣的類Bar
:
# bar.rb
require './foo'
class Bar < Foo
def initialize(param = 1)
end
end
我們有第一怪的東西,如果我們運行
x = Bar.new
我們只能得到1打印:foo_new
。和foo_init
??如果我們調用x = Bar.new
foo_new
和foo_init
:
好了,我們可以繞過這個問題將顯式調用的Foo
構造:
# bar.rb
require './foo'
class Bar < Foo
def initialize(param = 1)
super()
end
end
我們拿到的2幅版畫。
第二怪的東西是這樣的: 如果我們調用
x = Bar.new(2)
我們得到的錯誤
in `new': wrong number of arguments(1 for 0) (ArgumentError)
但Bar
構造接受默認值一個參數。
這是爲什麼?這是一個Ruby錯誤?
(與ruby1.9.3-P0測試[x86_64的])
'p Bar.new.class'輸出'Foo',對不對? –
'Bar.new.class'打印'Bar','Foo.new.class'打印'Foo' – Pioz