c - C 扩展中的 Ruby 关键字参数

标签 c ruby ruby-c-extension

如何处理来自 C 扩展的 Ruby 2.0.0 关键字参数?

背景

def example(name: 'Bob' hat_color: 'red')
  puts "#{name} has a #{hat_color} hat!"
end

example                                  #=> "Bob has a red hat!"
example(name: 'Joe', hat_color: 'blue')  #=> "Joe has a blue hat!"

关键字参数(如上)在处理具有许多不同调用序列或选项的方法时非常有用。我在 C 扩展中有一个这样的方法(一种处理我项目中大部分 OpenGL 绘图的 blit 方法),我想知道如何让该方法处理来自 ruby​​ 的关键字参数。

想法

根据我所做的一些研究,我认为这种处理可以通过 rb_scan_args 上的 : 选项来完成。 C函数。但是,我一直无法找到有关如何使用它的任何信息。

最佳答案

目前没有直接使用关键字参数的核心方法,即klass.instance_method(:method).parameters永远不会回来:key用于内置类。

您可能必须定义一个接受参数的方法,在本例中是一个散列并自己解析它。为此,您可以使用 rb_scan_args:获得 Hash 的参数来自最后一个参数(例如 dir_initialize )或类似于 OPTHASH_GIVEN_P 的代码宏(在 array.c 中)。从哈希中,您可以使用 rb_get_kwargs得到你想要的值(value)。如果您愿意,我还没有研究如何为无法识别的关键字参数生成错误。我认为大多数核心方法(至少目前)不执行此检查。

您可以使用关键字元素在 Ruby 中定义您的方法,并从那里调用内部 C 方法。这将为您免费提供正在检查的未知 key 和适当的 parameters。签名。

我希望通过修改后的 api 来改善这种情况,以在 Ruby 2.2 中定义方法,这将使在 C 函数中使用关键字参数等变得更加自然(参见 this issue)

关于c - C 扩展中的 Ruby 关键字参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20710440/

相关文章:

ruby-on-rails - Geocoder Gem - 获取 request.location.country 的 "Reserved"(即使在本地!)

ruby-on-rails - 如何使用 ruby​​ Base64 解码 utf8 字符

ruby C 扩展 : Is there a way to finalize?

ruby - 为什么要私有(private)封装私有(private)常量?

ruby - 庭院和 C 扩展

c - 函数的 IF 部分中的双重释放或损坏(顶部)

c - 修改并返回指向结构体的指针

c - C 标准是否强制要求平台不得定义超出标准中给出的行为

c - 你如何在 C 中扫描单个字符?