Home
Testing 1,2,3... - February 18th, 2005 [entries|archive|friends|userinfo]
djberg96

[ website | Sapphire ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Links
[Links:| Ruby Home RubyForge RAA comp.lang.ruby Ruby Documentation ]

February 18th, 2005

Use rb_scan_args dammit! [Feb. 18th, 2005|05:35 pm]
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. :)
linkpost comment

navigation
[ viewing | February 18th, 2005 ]
[ go | Previous Day|Next Day ]

Advertisement