如何将关键字从 C 扩展传递给 Ruby 方法?
How to pass keywords to a Ruby method from a C extension?
我正在为 Ruby 开发 C 扩展,我想调用一个需要关键字参数的方法,如下所示:
class Word
def initialize(line:, col:, value:)
end
end
在 C 中,我很熟悉通过 rb_funcall
和 rb_funcallv
调用 Ruby 方法,但我不知道如何传递关键字参数!
以下是我尝试过的一些方法:
使用 rb_funcall
:
将散列作为最后一个位置参数传递
VALUE kwargs = rb_hash_new();
rb_hash_aset(kwargs, rb_intern("name"), rb_str_new2(name));
// ...
rb_funcall(Word_Class, rb_intern("new"), 1, kwargs);
// result: ArgumentError: wrong number of arguments (given 1, expected 0)
将其作为 argv
数组的最后一个成员传递给 rb_funcallv
:
// initialize `kwargs` as above
VALUE argv = rb_ary_new();
rb_ary_push(argv, kwargs);
rb_funcallv(Word_Class, rb_intern("new"), 1, &argv);
// result: ArgumentError: wrong number of arguments (given 1, expected 0)
将 0
作为 argc
传递,即使 argv
是长度 1
:
// initialize `argv` as above
rb_funcallv(Word_Class, rb_intern("new"), 0, &argv);
// ArgumentError: missing keywords: line, col, value
可能吗?它是如何完成的?还有什么我可以尝试的吗?
你可以传入一个散列。请注意,要创建符号键,您需要调用 ID2SYM(rb_intern(char*))
形式,因为 rb_intern
returns 和 ID
,其中 ID2SYM
变成实际的 Ruby符号。
VALUE kwargs = rb_hash_new();
rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), rb_str_new2(name));
// ...
rb_funcall(Word_Class, ID2SYM(rb_intern("new")), 1, kwargs);
我正在为 Ruby 开发 C 扩展,我想调用一个需要关键字参数的方法,如下所示:
class Word
def initialize(line:, col:, value:)
end
end
在 C 中,我很熟悉通过 rb_funcall
和 rb_funcallv
调用 Ruby 方法,但我不知道如何传递关键字参数!
以下是我尝试过的一些方法:
使用 rb_funcall
:
VALUE kwargs = rb_hash_new();
rb_hash_aset(kwargs, rb_intern("name"), rb_str_new2(name));
// ...
rb_funcall(Word_Class, rb_intern("new"), 1, kwargs);
// result: ArgumentError: wrong number of arguments (given 1, expected 0)
将其作为 argv
数组的最后一个成员传递给 rb_funcallv
:
// initialize `kwargs` as above
VALUE argv = rb_ary_new();
rb_ary_push(argv, kwargs);
rb_funcallv(Word_Class, rb_intern("new"), 1, &argv);
// result: ArgumentError: wrong number of arguments (given 1, expected 0)
将 0
作为 argc
传递,即使 argv
是长度 1
:
// initialize `argv` as above
rb_funcallv(Word_Class, rb_intern("new"), 0, &argv);
// ArgumentError: missing keywords: line, col, value
可能吗?它是如何完成的?还有什么我可以尝试的吗?
你可以传入一个散列。请注意,要创建符号键,您需要调用 ID2SYM(rb_intern(char*))
形式,因为 rb_intern
returns 和 ID
,其中 ID2SYM
变成实际的 Ruby符号。
VALUE kwargs = rb_hash_new();
rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), rb_str_new2(name));
// ...
rb_funcall(Word_Class, ID2SYM(rb_intern("new")), 1, kwargs);