Ruby Keyword Arguments in C Extensions

How to handle Ruby 2.0.0 keyword arguments from a C extension?

Background

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!" 

Keyword arguments (such as the ones above) are very useful when processing methods that contain many different call sequences or options. I have one such method in extension C (the blit method that handles most of the OpenGL drawing in my project), and I am wondering how I can have a method keyword argument from ruby.

Ideas

Based on some research that I have done, I think that such processing can be performed using the option : on rb_scan_args C function. However, I could not find any information on how to use it for this.

+7
c ruby ruby-c-extension
source share
1 answer

There is no main method that currently directly uses keyword arguments, i.e. klass.instance_method(:method).parameters will never return :key for built-in classes.

You probably need to define a method that takes an argument, in this case a hash, and analyze it yourself. To do this, you can use rb_scan_args with the argument : to get Hash from the last argument (for example, dir_initialize ) or code similar to the OPTHASH_GIVEN_P macro (in array.c ). From the hash, you can use rb_get_kwargs to get the values ​​you need. I have not considered how to create an error for unrecognized keyword arguments if you wish. I think most basic methods do not perform this check (at least for now).

You could define your method in Ruby using keyword elements and call the internal C method from there. This will provide you with free unknown keys and the correct signature parameters .

I hope to improve this situation with a revised api to define methods in Ruby 2.2, which would make it more natural to use keyword arguments in C functions, among other things (see this question )

+5
source share

All Articles