Ruby Cエクステンションのクラスcostructorで奇妙な動作が見られました。
は、例を参照してください:我々は、Cの拡張とFoo
から継承するクラスBar
あるクラスFoo
を持っている:Ruby Cエクステンションのcostructorでの不思議な動作
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
もOKですが、奇妙な原料を見てみましょう...この状況で
すべてがOKに行く:foo_new
とfoo_init
:
x = Bar.new
我々は2枚のプリントを取得します。
[OK]を良い、しかし、我々はこのようにクラスBar
を変更した場合:foo_new
:
# bar.rb
require './foo'
class Bar < Foo
def initialize(param = 1)
end
end
は、我々が最初に奇妙なものを持っている私たちは
x = Bar.new
を実行した場合、我々は1つだけのプリントを得ます。そしてfoo_init
??
[OK]を、私たちはFoo
のコンストラクタに明示的な呼び出しを追加し、この問題を回避することができます
# bar.rb
require './foo'
class Bar < Foo
def initialize(param = 1)
super()
end
end
我々は2枚の印刷物を得る:我々はx = Bar.new
を呼び出す場合foo_new
とfoo_init
を。我々は
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