This is part 6 of the tale of my adventures in Ruby C extension land.
If you haven't read the other parts, you might want to go back there.
Defining Functions
In the last part, I showed how to define the two function types:
- Fixed argument count
- Variable argument count
Here's how to implement the according C functions:
Fixed Argument Count
VALUE juice(self, argument1, argument2)
VALUE self;
VALUE argument1;
VALUE argument2;
{
// ...
}
self
will point to the Ruby object this
function is a member of, e.g. Cranberry
if you called it as Cranberry.juice
.
The other arguments will be just that -- the function's arguments.
Ruby will ensure you always get the right amount of arguments.
Variable Argument Count 1 -- C Array
VALUE new(argc, argv, self)
int argc;
VALUE * argv;
VALUE self;
{
// ...
}
This one's more complex.
argc
will contain the number of arguments
passed to the function.
Ruby ensures you get at least the minimum
number of arguments you specified.
argv
will be a collection of the passed
arguments. You won't manipulate this directly.
self
is the same as above.
Argument Checking
With this version, you will have to
explicitly retrieve the arguments from
argv
.
For this you use rb_scan_args
.
It takes in argc
, argv
, the number
of required and optional arguments and pointers
to the VALUE
objects to fill with these
arguments:
VALUE cranberry;
VALUE optional;
rb_scan_args(argc, argv, "11", &cranberry, &optional);
The nice thing about rb_scan_args
, though, is
that it will raise a Ruby exception when the
argument count is not as expected.
As you can see, "11"
is the string that tells
rb_scan_args
how many arguments you expect:
one mandatory, one optional.
To further illustrate, here's a list of Ruby
definitions and their rb_scan_args
equivalents:
def foo( arg = nil )
rb_scan_args(argc, argv, "01", &arg);
def foo( &block )
rb_scan_args(argc, argv, "0&", &block);
def foo( *args )
rb_scan_args(argc, argv, "0*", &args);
def foo( arg, opt = nil, *args, &block )
rb_scan_args(argc, argv, "11*&", &arg, &opt, &args, &block);
I think you get the scheme...
Any optional arguments and the block argument
will be set to nil
if they were left out.
Variable Argument Count 2 -- Ruby Array
VALUE new(self, args)
VALUE self;
VALUE args;
{
// ...
}
This one's easy again: Just use args
as the
Ruby array it is.
OK, now while you digest this big hunk of information, I will dream about the next piece of this fine saga.