Two method objects are equal if that are bound to the same object and contain the same body.
static VALUE method_eq(method, other) VALUE method, other; { struct METHOD *m1, *m2; if (TYPE(other) != T_DATA || RDATA(other)->dmark != (RUBY_DATA_FUNC)bm_mark) return Qfalse; if (CLASS_OF(method) != CLASS_OF(other)) return Qfalse; Data_Get_Struct(method, struct METHOD, m1); Data_Get_Struct(other, struct METHOD, m2); if (m1->klass != m2->klass || m1->rklass != m2->rklass || m1->recv != m2->recv || m1->body != m2->body) return Qfalse; return Qtrue; }
Invokes the meth with the specified arguments, returning the method's return value.
m = 12.method("+") m.call(3) #=> 15 m.call(20) #=> 32
static VALUE method_call(argc, argv, method) int argc; VALUE *argv; VALUE method; { VALUE result = Qnil; /* OK */ struct METHOD *data; int safe; Data_Get_Struct(method, struct METHOD, data); if (data->recv == Qundef) { rb_raise(rb_eTypeError, "can't call unbound method; bind first"); } if (OBJ_TAINTED(method)) { safe = NOEX_WITH(data->safe_level, 4)|NOEX_TAINTED; } else { safe = data->safe_level; } PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT); result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,safe); POP_ITER(); return result; }
Returns an indication of the number of arguments accepted by a method. Returns a nonnegative integer for methods that take a fixed number of arguments. For Ruby methods that take a variable number of arguments, returns -n-1, where n is the number of required arguments. For methods written in C, returns -1 if the call takes a variable number of arguments.
class C def one; end def two(a); end def three(*a); end def four(a, b); end def five(a, b, *c); end def six(a, b, *c, &d); end end c = C.new c.method(:one).arity #=> 0 c.method(:two).arity #=> 1 c.method(:three).arity #=> -1 c.method(:four).arity #=> 2 c.method(:five).arity #=> -3 c.method(:six).arity #=> -3 "cat".method(:size).arity #=> 0 "cat".method(:replace).arity #=> 1 "cat".method(:squeeze).arity #=> -1 "cat".method(:count).arity #=> -1
static VALUE method_arity(method) VALUE method; { struct METHOD *data; NODE *body; int n; Data_Get_Struct(method, struct METHOD, data); body = data->body; switch (nd_type(body)) { case NODE_CFUNC: if (body->nd_argc < 0) return INT2FIX(-1); return INT2FIX(body->nd_argc); case NODE_ZSUPER: return INT2FIX(-1); case NODE_ATTRSET: return INT2FIX(1); case NODE_IVAR: return INT2FIX(0); case NODE_BMETHOD: return proc_arity(body->nd_cval); case NODE_DMETHOD: return method_arity(body->nd_cval); case NODE_SCOPE: body = body->nd_next; /* skip NODE_SCOPE */ if (nd_type(body) == NODE_BLOCK) body = body->nd_head; if (!body) return INT2FIX(0); n = body->nd_cnt; if (body->nd_opt || body->nd_rest) n = -n-1; return INT2FIX(n); default: rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body)); } }
Invokes the meth with the specified arguments, returning the method's return value.
m = 12.method("+") m.call(3) #=> 15 m.call(20) #=> 32
static VALUE method_call(argc, argv, method) int argc; VALUE *argv; VALUE method; { VALUE result = Qnil; /* OK */ struct METHOD *data; int safe; Data_Get_Struct(method, struct METHOD, data); if (data->recv == Qundef) { rb_raise(rb_eTypeError, "can't call unbound method; bind first"); } if (OBJ_TAINTED(method)) { safe = NOEX_WITH(data->safe_level, 4)|NOEX_TAINTED; } else { safe = data->safe_level; } PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT); result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,safe); POP_ITER(); return result; }
MISSING: documentation
static VALUE method_clone(self) VALUE self; { VALUE clone; struct METHOD *orig, *data; Data_Get_Struct(self, struct METHOD, orig); clone = Data_Make_Struct(CLASS_OF(self),struct METHOD, bm_mark, free, data); CLONESETUP(clone, self); *data = *orig; return clone; }
Show the name of the underlying method.
"cat".method(:count).inspect #=> "#<Method: String#count>"
static VALUE method_inspect(method) VALUE method; { struct METHOD *data; VALUE str; const char *s; char *sharp = "#"; Data_Get_Struct(method, struct METHOD, data); str = rb_str_buf_new2("#<"); s = rb_obj_classname(method); rb_str_buf_cat2(str, s); rb_str_buf_cat2(str, ": "); if (FL_TEST(data->klass, FL_SINGLETON)) { VALUE v = rb_iv_get(data->klass, "__attached__"); if (data->recv == Qundef) { rb_str_buf_append(str, rb_inspect(data->klass)); } else if (data->recv == v) { rb_str_buf_append(str, rb_inspect(v)); sharp = "."; } else { rb_str_buf_append(str, rb_inspect(data->recv)); rb_str_buf_cat2(str, "("); rb_str_buf_append(str, rb_inspect(v)); rb_str_buf_cat2(str, ")"); sharp = "."; } } else { rb_str_buf_cat2(str, rb_class2name(data->rklass)); if (data->rklass != data->klass) { VALUE klass = data -> klass; if (TYPE(klass) == T_ICLASS) { klass = RBASIC(klass)->klass; } rb_str_buf_cat2(str, "("); rb_str_buf_cat2(str, rb_class2name(klass)); rb_str_buf_cat2(str, ")"); } } rb_str_buf_cat2(str, sharp); rb_str_buf_cat2(str, rb_id2name(data->oid)); rb_str_buf_cat2(str, ">"); return str; }
Returns a Proc
object corresponding to this method.
static VALUE method_proc(method) VALUE method; { VALUE proc; struct METHOD *mdata; struct BLOCK *bdata; proc = rb_iterate((VALUE(*)_((VALUE)))mproc, 0, bmcall, method); Data_Get_Struct(method, struct METHOD, mdata); Data_Get_Struct(proc, struct BLOCK, bdata); bdata->body->nd_file = mdata->body->nd_file; nd_set_line(bdata->body, nd_line(mdata->body)); bdata->body->nd_state = YIELD_FUNC_SVALUE; return proc; }
Show the name of the underlying method.
"cat".method(:count).inspect #=> "#<Method: String#count>"
static VALUE method_inspect(method) VALUE method; { struct METHOD *data; VALUE str; const char *s; char *sharp = "#"; Data_Get_Struct(method, struct METHOD, data); str = rb_str_buf_new2("#<"); s = rb_obj_classname(method); rb_str_buf_cat2(str, s); rb_str_buf_cat2(str, ": "); if (FL_TEST(data->klass, FL_SINGLETON)) { VALUE v = rb_iv_get(data->klass, "__attached__"); if (data->recv == Qundef) { rb_str_buf_append(str, rb_inspect(data->klass)); } else if (data->recv == v) { rb_str_buf_append(str, rb_inspect(v)); sharp = "."; } else { rb_str_buf_append(str, rb_inspect(data->recv)); rb_str_buf_cat2(str, "("); rb_str_buf_append(str, rb_inspect(v)); rb_str_buf_cat2(str, ")"); sharp = "."; } } else { rb_str_buf_cat2(str, rb_class2name(data->rklass)); if (data->rklass != data->klass) { VALUE klass = data -> klass; if (TYPE(klass) == T_ICLASS) { klass = RBASIC(klass)->klass; } rb_str_buf_cat2(str, "("); rb_str_buf_cat2(str, rb_class2name(klass)); rb_str_buf_cat2(str, ")"); } } rb_str_buf_cat2(str, sharp); rb_str_buf_cat2(str, rb_id2name(data->oid)); rb_str_buf_cat2(str, ">"); return str; }
Dissociates meth from it's current receiver. The resulting
UnboundMethod
can subsequently be bound to a new object of the
same class (see UnboundMethod
).
static VALUE method_unbind(obj) VALUE obj; { VALUE method; struct METHOD *orig, *data; Data_Get_Struct(obj, struct METHOD, orig); method = Data_Make_Struct(rb_cUnboundMethod, struct METHOD, bm_mark, free, data); data->klass = orig->klass; data->recv = Qundef; data->id = orig->id; data->body = orig->body; data->rklass = orig->rklass; data->oid = orig->oid; OBJ_INFECT(method, obj); return method; }