ruby - 如何从 C 扩展将关键字传递到 Ruby 方法?

标签 ruby ruby-c-extension keyword-argument

我正在为 Ruby 开发 C 扩展,我想调用一个需要关键字参数的方法,如下所示:

class Word 
  def initialize(line:, col:, value:)
  end 
end 

在 C 中,我很熟悉通过 rb_funcallrb_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/

相关文章:

python - 如何将变量值作为关键字参数键传递?

ruby - 选择工具集 : scala, ruby​​、java 等

ruby-on-rails - 我如何从 Ruby 代码连接到 mongodb?

ruby - 除了实际元素之外,Nokogiri XML.children 还返回格式化元素。如何避免这种情况?

javascript 改变 ruby​​ 变量

c - Ruby C 扩展 API 问题

c - 为什么我的 C 扩展没有创建唯一实例?

c - 如何检索从 ruby​​ 脚本传递的 C 中结构类型变量的结构成员?

python - 每次在 Python 中调用函数时改变不同的参数

python-3.x - 传递一个集合来打印,在Python 3中使用分隔符打印?