method_missing(...)
public
Invoked by Ruby when obj is sent a message it cannot handle.
symbol is the symbol for the method called, and args are
any arguments that were passed to it. By default, the interpreter raises an
error when this method is called. However, it is possible to override the
method to provide more dynamic behavior. The example below creates a class
Roman, which responds to methods with names consisting of roman
numerals, returning the corresponding integer values.
class Roman
def romanToInt(str)
end
def method_missing(methId)
str = methId.id2name
romanToInt(str)
end
end
r = Roman.new
r.iv
r.xxiii
r.mm
Show source
/*
* call-seq:
* obj.method_missing(symbol [, *args] ) => result
*
* Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
* <i>symbol</i> is the symbol for the method called, and <i>args</i>
* are any arguments that were passed to it. By default, the interpreter
* raises an error when this method is called. However, it is possible
* to override the method to provide more dynamic behavior.
* The example below creates
* a class <code>Roman</code>, which responds to methods with names
* consisting of roman numerals, returning the corresponding integer
* values.
*
* class Roman
* def romanToInt(str)
* # ...
* end
* def method_missing(methId)
* str = methId.id2name
* romanToInt(str)
* end
* end
*
* r = Roman.new
* r.iv #=> 4
* r.xxiii #=> 23
* r.mm #=> 2000
*/
static VALUE
rb_method_missing(argc, argv, obj)
int argc;
VALUE *argv;
VALUE obj;
{
ID id;
VALUE exc = rb_eNoMethodError;
const char *format = 0;
NODE *cnode = ruby_current_node;
if (argc == 0 || !SYMBOL_P(argv[0])) {
rb_raise(rb_eArgError, "no id given");
}
stack_check();
id = SYM2ID(argv[0]);
if (last_call_status & CSTAT_PRIV) {
format = "private method `%s' called for %s";
}
else if (last_call_status & CSTAT_PROT) {
format = "protected method `%s' called for %s";
}
else if (last_call_status & CSTAT_VCALL) {
format = "undefined local variable or method `%s' for %s";
exc = rb_eNameError;
}
else if (last_call_status & CSTAT_SUPER) {
format = "super: no superclass method `%s'";
}
if (!format) {
format = "undefined method `%s' for %s";
}
ruby_current_node = cnode;
{
int n = 0;
VALUE args[3];
args[n++] = rb_funcall(rb_const_get(exc, rb_intern("message")), '!',
3, rb_str_new2(format), obj, argv[0]);
args[n++] = argv[0];
if (exc == rb_eNoMethodError) {
args[n++] = rb_ary_new4(argc-1, argv+1);
}
exc = rb_class_new_instance(n, args, exc);
ruby_frame = ruby_frame->prev; /* pop frame for "method_missing" */
rb_exc_raise(exc);
}
return Qnil; /* not reached */
}