method_missing is a very useful tool for dynamic programming.
It is easy to implement in ruby:
class Fren
def method_missing(*info)
puts "method called: #{info.shift} does not exist"
puts "received parameters:"
info.each { |v| puts v }
end
end
The parameters passed to method_missing include the symbol for the ‘method’ along with any arguments. The parameters are stored in the ‘info’ array, and, in the example above are printed out to the user.
How do we implement this functionality in C?
static VALUE
m_missing(int argc, VALUE * argv, VALUE self) {
VALUE method_name;
VALUE args;
char * c_string;
int val;
int i=0;
/* store the method name and arguments in separate variables */
rb_scan_args(argc, argv, "1*",&method_name,&args);
/* convert the method_name from a ruby Symbol to a c char* */
c_string=rb_id2name(SYM2ID(method_name));
printf("method called: %s does not exist\n",c_string);
printf("received parameters:\n");
/* for simplicity, assume that all arguments are integers */
for(i=0;i<RARRAY(args)->len;i++) {
val=NUM2INT(rb_ary_entry(args,i));
printf("%d\n",val);
}
return Qnil;
}
And here is our ruby binding:
rb_define_method(myclass, "method_missing", m_missing, -1);
Note we use ‘-1′ as our parameter-count for rb_define_method. The ‘-1′ indicates a variable number of parameters; this means that our function must be prototyped as follows:
static VALUE m_missing(int argc, VALUE *argv, VALUE self);
Where argc is the number of arguments passed, argv a pointer to an array of those arguments, and self is a pointer to the object instance.
The above C and Ruby code should perform pretty much identically.
Filed under: C, metaprogramming, programming, ruby | Tagged: C, C extension, method_missing, ruby