This post originated from an RSS feed registered with Ruby Buzz
by Daniel Berger.
Original Post: Use rb_scan_args dammit!
Feed Title: Testing 1,2,3...
Feed URL: http://djberg96.livejournal.com/data/rss
Feed Description: A blog on Ruby and other stuff.
Here's another tip for folks writing extensions with Ruby: don't count arguments manually using argc. Use rb_scan_args() instead.
This has a few advantages. First, it's shorter. Second, it's less error prone. Third, you don't have to manually raise an ArgumentError if the argument count is wrong.
Consider the following bad example:
static VALUE some_func(int argc, VALUE* argv){
VALUE rbFoo;
if(argc == 0){
rbFoo = FIX2INT(1);
}
else if(argc == 1){
rbFoo = argv[0];
}
else{
rb_raise(rb_eArgumentError,"wrong number of arguments");
}
return rbFoo;
}
Now compare that against the good example:
static VALUE some_func(int argc, VALUE* argv){
VALUE rbFoo;
rb_scan_args(argc,argv,"01",&rbFoo); // 0 or 1 argument
if(NIL_P(rbFoo)){
rbFoo = FIX2INT(1);
}
return rbFoo;
}
The second example is less code (and could be shortened even further with a ternary operation), less error prone (no chance of making a mistake counting arguments), and automatically raises an ArgumentError (with slightly more information than the bad example) if you try to pass more than 1 argument.
Guy Decoux suggested that counting argc manually was faster. However, my benchmarks show that there is no significant difference.
Generally speaking, I noticed that the folks counting argc manually are trying to simulate function overloading in their C code. That's bad, because it means they probably didn't think out their Ruby API first. Always, always, always flesh out the Ruby side of your code first before you start digging into the C side of things. You have default arguments in Ruby - use them. Don't resort to "if 1 argument, do X; if 2 arguments do Y" behavior. I like C, too, but only on the backend. :)