我正在为 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)
使用rb_funcallv
将其作为argv
数组的最后一个成员传递:
// 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
返回一个 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 扩展将关键字传递到 Ruby 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40315555/