Skip to content

Instantly share code, notes, and snippets.

@banister
Created March 23, 2011 05:04
Show Gist options
  • Save banister/882648 to your computer and use it in GitHub Desktop.
Save banister/882648 to your computer and use it in GitHub Desktop.
pry(Module):4> show-method define_method
--
From Ruby Core (C Method):
--
static VALUE
rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
{
ID id;
VALUE body;
int noex = NOEX_PUBLIC;
if (argc == 1) {
id = rb_to_id(argv[0]);
body = rb_block_lambda();
}
else if (argc == 2) {
id = rb_to_id(argv[0]);
body = argv[1];
if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) {
rb_raise(rb_eTypeError,
"wrong argument type %s (expected Proc/Method)",
rb_obj_classname(body));
}
}
else {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
}
if (rb_obj_is_method(body)) {
struct METHOD *method = (struct METHOD *)DATA_PTR(body);
VALUE rclass = method->rclass;
if (rclass != mod && !RTEST(rb_class_inherited_p(mod, rclass))) {
if (FL_TEST(rclass, FL_SINGLETON)) {
rb_raise(rb_eTypeError,
"can't bind singleton method to a different class");
}
else {
rb_raise(rb_eTypeError,
"bind argument must be a subclass of %s",
rb_class2name(rclass));
}
}
rb_method_entry_set(mod, id, &method->me, noex);
}
else if (rb_obj_is_proc(body)) {
rb_proc_t *proc;
body = proc_dup(body);
GetProcPtr(body, proc);
if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) {
proc->block.iseq->defined_method_id = id;
proc->block.iseq->klass = mod;
proc->is_lambda = TRUE;
proc->is_from_method = TRUE;
}
rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)body, noex);
}
else {
/* type error */
rb_raise(rb_eTypeError, "wrong argument type (expected Proc/Method)");
}
return body;
}
=> nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment