Two method objects are equal if they are bound to the same object and refer to the same method definition.
static VALUE method_eq(VALUE method, VALUE other) { struct METHOD *m1, *m2; if (!rb_obj_is_method(other)) return Qfalse; if (CLASS_OF(method) != CLASS_OF(other)) return Qfalse; Check_TypedStruct(method, &method_data_type); m1 = (struct METHOD *)DATA_PTR(method); m2 = (struct METHOD *)DATA_PTR(other); if (!rb_method_entry_eq(m1->me, m2->me) || m1->rclass != m2->rclass || m1->recv != m2->recv) { 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
VALUE rb_method_call(int argc, VALUE *argv, VALUE method) { VALUE result = Qnil; /* OK */ struct METHOD *data; int state; volatile int safe = -1; TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); if (data->recv == Qundef) { rb_raise(rb_eTypeError, "can't call unbound method; bind first"); } PUSH_TAG(); if (OBJ_TAINTED(method)) { safe = rb_safe_level(); if (rb_safe_level() < 4) { rb_set_safe_level_force(4); } } if ((state = EXEC_TAG()) == 0) { rb_thread_t *th = GET_THREAD(); PASS_PASSED_BLOCK_TH(th); result = rb_vm_call(th, data->recv, data->id, argc, argv, data->me); } POP_TAG(); if (safe >= 0) rb_set_safe_level_force(safe); if (state) JUMP_TAG(state); 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_m(VALUE method) { int n = method_arity(method); return INT2FIX(n); }
Invokes the meth with the specified arguments, returning the method’s return value.
m = 12.method("+") m.call(3) #=> 15 m.call(20) #=> 32
VALUE rb_method_call(int argc, VALUE *argv, VALUE method) { VALUE result = Qnil; /* OK */ struct METHOD *data; int state; volatile int safe = -1; TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); if (data->recv == Qundef) { rb_raise(rb_eTypeError, "can't call unbound method; bind first"); } PUSH_TAG(); if (OBJ_TAINTED(method)) { safe = rb_safe_level(); if (rb_safe_level() < 4) { rb_set_safe_level_force(4); } } if ((state = EXEC_TAG()) == 0) { rb_thread_t *th = GET_THREAD(); PASS_PASSED_BLOCK_TH(th); result = rb_vm_call(th, data->recv, data->id, argc, argv, data->me); } POP_TAG(); if (safe >= 0) rb_set_safe_level_force(safe); if (state) JUMP_TAG(state); return result; }
MISSING: documentation
static VALUE method_clone(VALUE self) { VALUE clone; struct METHOD *orig, *data; TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig); clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data); CLONESETUP(clone, self); *data = *orig; data->me = ALLOC(rb_method_entry_t); *data->me = *orig->me; if (data->me->def) data->me->def->alias_count++; data->ume = ALLOC(struct unlinked_method_entry_list_entry); return clone; }
Two method objects are equal if they are bound to the same object and refer to the same method definition.
static VALUE method_eq(VALUE method, VALUE other) { struct METHOD *m1, *m2; if (!rb_obj_is_method(other)) return Qfalse; if (CLASS_OF(method) != CLASS_OF(other)) return Qfalse; Check_TypedStruct(method, &method_data_type); m1 = (struct METHOD *)DATA_PTR(method); m2 = (struct METHOD *)DATA_PTR(other); if (!rb_method_entry_eq(m1->me, m2->me) || m1->rclass != m2->rclass || m1->recv != m2->recv) { return Qfalse; } return Qtrue; }
Returns a hash value corresponding to the method object.
static VALUE method_hash(VALUE method) { struct METHOD *m; st_index_t hash; TypedData_Get_Struct(method, struct METHOD, &method_data_type, m); hash = rb_hash_start((st_index_t)m->rclass); hash = rb_hash_uint(hash, (st_index_t)m->recv); hash = rb_hash_uint(hash, (st_index_t)m->me->def); hash = rb_hash_end(hash); return INT2FIX(hash); }
Returns the name of the underlying method.
"cat".method(:count).inspect #=> "#<Method: String#count>"
static VALUE method_inspect(VALUE method) { struct METHOD *data; VALUE str; const char *s; const char *sharp = "#"; TypedData_Get_Struct(method, struct METHOD, &method_data_type, 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->me->klass, FL_SINGLETON)) { VALUE v = rb_iv_get(data->me->klass, "__attached__"); if (data->recv == Qundef) { rb_str_buf_append(str, rb_inspect(data->me->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->rclass)); if (data->rclass != data->me->klass) { rb_str_buf_cat2(str, "("); rb_str_buf_cat2(str, rb_class2name(data->me->klass)); rb_str_buf_cat2(str, ")"); } } rb_str_buf_cat2(str, sharp); rb_str_append(str, rb_id2str(data->me->def->original_id)); if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) { rb_str_buf_cat2(str, " (not-implemented)"); } rb_str_buf_cat2(str, ">"); return str; }
Returns the name of the method.
static VALUE method_name(VALUE obj) { struct METHOD *data; TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data); return ID2SYM(data->id); }
Returns the class or module that defines the method.
static VALUE method_owner(VALUE obj) { struct METHOD *data; TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data); return data->me->klass; }
Returns the parameter information of this method.
static VALUE rb_method_parameters(VALUE method) { rb_iseq_t *iseq = rb_method_get_iseq(method); if (!iseq) { return unnamed_parameters(method_arity(method)); } return rb_iseq_parameters(iseq, 0); }
Returns the bound receiver of the method object.
static VALUE method_receiver(VALUE obj) { struct METHOD *data; TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data); return data->recv; }
Returns the Ruby source filename and line number containing this method or nil if this method was not defined in Ruby (i.e. native)
VALUE rb_method_location(VALUE method) { rb_method_definition_t *def = method_get_def(method); if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) { if (!def->body.attr.location) return Qnil; return rb_ary_dup(def->body.attr.location); } return iseq_location(method_get_iseq(def)); }
Returns a Proc
object corresponding to this method.
static VALUE method_proc(VALUE method) { VALUE procval; rb_proc_t *proc; /* * class Method * def to_proc * proc{|*args| * self.call(*args) * } * end * end */ procval = rb_iterate(mlambda, 0, bmcall, method); GetProcPtr(procval, proc); proc->is_from_method = 1; return procval; }
Returns the name of the underlying method.
"cat".method(:count).inspect #=> "#<Method: String#count>"
static VALUE method_inspect(VALUE method) { struct METHOD *data; VALUE str; const char *s; const char *sharp = "#"; TypedData_Get_Struct(method, struct METHOD, &method_data_type, 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->me->klass, FL_SINGLETON)) { VALUE v = rb_iv_get(data->me->klass, "__attached__"); if (data->recv == Qundef) { rb_str_buf_append(str, rb_inspect(data->me->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->rclass)); if (data->rclass != data->me->klass) { rb_str_buf_cat2(str, "("); rb_str_buf_cat2(str, rb_class2name(data->me->klass)); rb_str_buf_cat2(str, ")"); } } rb_str_buf_cat2(str, sharp); rb_str_append(str, rb_id2str(data->me->def->original_id)); if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) { rb_str_buf_cat2(str, " (not-implemented)"); } rb_str_buf_cat2(str, ">"); return str; }
Dissociates meth from its current receiver. The resulting
UnboundMethod
can subsequently be bound to a new object of the
same class (see UnboundMethod
).
static VALUE method_unbind(VALUE obj) { VALUE method; struct METHOD *orig, *data; TypedData_Get_Struct(obj, struct METHOD, &method_data_type, orig); method = TypedData_Make_Struct(rb_cUnboundMethod, struct METHOD, &method_data_type, data); data->recv = Qundef; data->id = orig->id; data->me = ALLOC(rb_method_entry_t); *data->me = *orig->me; if (orig->me->def) orig->me->def->alias_count++; data->rclass = orig->rclass; data->ume = ALLOC(struct unlinked_method_entry_list_entry); OBJ_INFECT(method, obj); return method; }
Commenting is here to help enhance the documentation. For example, sample code, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.