1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* eval.c, gc.c, iseq.c, node.h, vm_insnhelper.c, vm_insnhelper.h,

vm_method.c: rename omod and overlaid modules to refinements.

* eval.c (hidden_identity_hash_new): renamed from identity_hash_new.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37117 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2012-10-08 14:02:46 +00:00
parent 7b6e6ede60
commit e028d3d905
11 changed files with 84 additions and 71 deletions

View file

@ -1,3 +1,10 @@
Mon Oct 8 23:02:19 2012 Shugo Maeda <shugo@ruby-lang.org>
* eval.c, gc.c, iseq.c, node.h, vm_insnhelper.c, vm_insnhelper.h,
vm_method.c: rename omod and overlaid modules to refinements.
* eval.c (hidden_identity_hash_new): renamed from identity_hash_new.
Sun Oct 7 04:50:00 2012 Zachary Scott <zzak@ruby-lang.org> Sun Oct 7 04:50:00 2012 Zachary Scott <zzak@ruby-lang.org>
* lib/abbrev.rb: Documentation examples for Abbrev. * lib/abbrev.rb: Documentation examples for Abbrev.

58
eval.c
View file

@ -1041,35 +1041,35 @@ void check_class_or_module(VALUE obj)
} }
static VALUE static VALUE
identity_hash_new() hidden_identity_hash_new()
{ {
VALUE hash = rb_hash_new(); VALUE hash = rb_hash_new();
rb_funcall(hash, rb_intern("compare_by_identity"), 0); rb_funcall(hash, rb_intern("compare_by_identity"), 0);
RBASIC(hash)->klass = 0; RBASIC(hash)->klass = 0; /* hide from ObjectSpace */
return hash; return hash;
} }
void void
rb_overlay_module(NODE *cref, VALUE klass, VALUE module) rb_using_refinement(NODE *cref, VALUE klass, VALUE module)
{ {
VALUE iclass, c, superclass = klass; VALUE iclass, c, superclass = klass;
check_class_or_module(klass); check_class_or_module(klass);
Check_Type(module, T_MODULE); Check_Type(module, T_MODULE);
if (NIL_P(cref->nd_omod)) { if (NIL_P(cref->nd_refinements)) {
cref->nd_omod = identity_hash_new(); cref->nd_refinements = hidden_identity_hash_new();
} }
else { else {
if (cref->flags & NODE_FL_CREF_OMOD_SHARED) { if (cref->flags & NODE_FL_CREF_OMOD_SHARED) {
cref->nd_omod = rb_hash_dup(cref->nd_omod); cref->nd_refinements = rb_hash_dup(cref->nd_refinements);
cref->flags &= ~NODE_FL_CREF_OMOD_SHARED; cref->flags &= ~NODE_FL_CREF_OMOD_SHARED;
} }
if (!NIL_P(c = rb_hash_lookup(cref->nd_omod, klass))) { if (!NIL_P(c = rb_hash_lookup(cref->nd_refinements, klass))) {
superclass = c; superclass = c;
while (c && TYPE(c) == T_ICLASS) { while (c && TYPE(c) == T_ICLASS) {
if (RBASIC(c)->klass == module) { if (RBASIC(c)->klass == module) {
/* already overlaid module */ /* already used refinement */
return; return;
} }
c = RCLASS_SUPER(c); c = RCLASS_SUPER(c);
@ -1086,7 +1086,7 @@ rb_overlay_module(NODE *cref, VALUE klass, VALUE module)
RCLASS_REFINED_CLASS(c) = klass; RCLASS_REFINED_CLASS(c) = klass;
module = RCLASS_SUPER(module); module = RCLASS_SUPER(module);
} }
rb_hash_aset(cref->nd_omod, klass, iclass); rb_hash_aset(cref->nd_refinements, klass, iclass);
rb_clear_cache_by_class(klass); rb_clear_cache_by_class(klass);
} }
@ -1095,21 +1095,21 @@ using_module_i(VALUE klass, VALUE module, VALUE arg)
{ {
NODE *cref = (NODE *) arg; NODE *cref = (NODE *) arg;
rb_overlay_module(cref, klass, module); rb_using_refinement(cref, klass, module);
return ST_CONTINUE; return ST_CONTINUE;
} }
void void
rb_using_module(NODE *cref, VALUE module) rb_using_module(NODE *cref, VALUE module)
{ {
ID id_overlaid_modules; ID id_refinements;
VALUE overlaid_modules; VALUE refinements;
check_class_or_module(module); check_class_or_module(module);
CONST_ID(id_overlaid_modules, "__overlaid_modules__"); CONST_ID(id_refinements, "__refinements__");
overlaid_modules = rb_attr_get(module, id_overlaid_modules); refinements = rb_attr_get(module, id_refinements);
if (NIL_P(overlaid_modules)) return; if (NIL_P(refinements)) return;
rb_hash_foreach(overlaid_modules, using_module_i, (VALUE) cref); rb_hash_foreach(refinements, using_module_i, (VALUE) cref);
} }
/* /*
@ -1130,7 +1130,7 @@ rb_mod_using(VALUE self, VALUE module)
CONST_ID(id_using_modules, "__using_modules__"); CONST_ID(id_using_modules, "__using_modules__");
using_modules = rb_attr_get(self, id_using_modules); using_modules = rb_attr_get(self, id_using_modules);
if (NIL_P(using_modules)) { if (NIL_P(using_modules)) {
using_modules = identity_hash_new(); using_modules = hidden_identity_hash_new();
rb_ivar_set(self, id_using_modules, using_modules); rb_ivar_set(self, id_using_modules, using_modules);
} }
rb_hash_aset(using_modules, module, Qtrue); rb_hash_aset(using_modules, module, Qtrue);
@ -1170,8 +1170,8 @@ refinement_module_include(int argc, VALUE *argv, VALUE module)
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) { while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) && if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) &&
(cref = rb_vm_get_cref(cfp->iseq, cfp->ep)) && (cref = rb_vm_get_cref(cfp->iseq, cfp->ep)) &&
!NIL_P(cref->nd_omod) && !NIL_P(cref->nd_refinements) &&
!NIL_P(c = rb_hash_lookup(cref->nd_omod, klass))) { !NIL_P(c = rb_hash_lookup(cref->nd_refinements, klass))) {
while (argc--) { while (argc--) {
VALUE mod = argv[argc]; VALUE mod = argv[argc];
if (rb_class_inherited_p(module, mod)) { if (rb_class_inherited_p(module, mod)) {
@ -1200,17 +1200,17 @@ rb_mod_refine(VALUE module, VALUE klass)
{ {
NODE *cref = rb_vm_cref(); NODE *cref = rb_vm_cref();
VALUE mod; VALUE mod;
ID id_overlaid_modules, id_refined_class; ID id_refinements, id_refined_class;
VALUE overlaid_modules; VALUE refinements;
check_class_or_module(klass); check_class_or_module(klass);
CONST_ID(id_overlaid_modules, "__overlaid_modules__"); CONST_ID(id_refinements, "__refinements__");
overlaid_modules = rb_attr_get(module, id_overlaid_modules); refinements = rb_attr_get(module, id_refinements);
if (NIL_P(overlaid_modules)) { if (NIL_P(refinements)) {
overlaid_modules = identity_hash_new(); refinements = hidden_identity_hash_new();
rb_ivar_set(module, id_overlaid_modules, overlaid_modules); rb_ivar_set(module, id_refinements, refinements);
} }
mod = rb_hash_lookup(overlaid_modules, klass); mod = rb_hash_lookup(refinements, klass);
if (NIL_P(mod)) { if (NIL_P(mod)) {
mod = rb_module_new(); mod = rb_module_new();
CONST_ID(id_refined_class, "__refined_class__"); CONST_ID(id_refined_class, "__refined_class__");
@ -1219,8 +1219,8 @@ rb_mod_refine(VALUE module, VALUE klass)
refinement_module_method_added, 1); refinement_module_method_added, 1);
rb_define_singleton_method(mod, "include", rb_define_singleton_method(mod, "include",
refinement_module_include, -1); refinement_module_include, -1);
rb_overlay_module(cref, klass, mod); rb_using_refinement(cref, klass, mod);
rb_hash_aset(overlaid_modules, klass, mod); rb_hash_aset(refinements, klass, mod);
} }
rb_mod_module_eval(0, NULL, mod); rb_mod_module_eval(0, NULL, mod);
return mod; return mod;

2
gc.c
View file

@ -2733,7 +2733,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr)
break; break;
case NODE_CREF: case NODE_CREF:
gc_mark(objspace, obj->as.node.nd_omod); gc_mark(objspace, obj->as.node.nd_refinements);
gc_mark(objspace, (VALUE)obj->as.node.u1.node); gc_mark(objspace, (VALUE)obj->as.node.u1.node);
ptr = (VALUE)obj->as.node.u3.node; ptr = (VALUE)obj->as.node.u3.node;
goto again; goto again;

View file

@ -1027,7 +1027,7 @@ invokesuper
if (me && me->def->type == VM_METHOD_TYPE_ISEQ && if (me && me->def->type == VM_METHOD_TYPE_ISEQ &&
me->def->body.iseq == ip) { me->def->body.iseq == ip) {
klass = RCLASS_SUPER(klass); klass = RCLASS_SUPER(klass);
me = rb_method_entry_get_with_omod(Qnil, klass, id, &klass); me = rb_method_entry_get_with_refinements(Qnil, klass, id, &klass);
} }
CALL_METHOD(num, blockptr, flag, id, me, recv, klass); CALL_METHOD(num, blockptr, flag, id, me, recv, klass);

8
iseq.c
View file

@ -202,11 +202,11 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
if (type == ISEQ_TYPE_TOP) { if (type == ISEQ_TYPE_TOP) {
/* toplevel is private */ /* toplevel is private */
iseq->cref_stack = NEW_CREF(rb_cObject); iseq->cref_stack = NEW_CREF(rb_cObject);
iseq->cref_stack->nd_omod = Qnil; iseq->cref_stack->nd_refinements = Qnil;
iseq->cref_stack->nd_visi = NOEX_PRIVATE; iseq->cref_stack->nd_visi = NOEX_PRIVATE;
if (th->top_wrapper) { if (th->top_wrapper) {
NODE *cref = NEW_CREF(th->top_wrapper); NODE *cref = NEW_CREF(th->top_wrapper);
cref->nd_omod = Qnil; cref->nd_refinements = Qnil;
cref->nd_visi = NOEX_PRIVATE; cref->nd_visi = NOEX_PRIVATE;
cref->nd_next = iseq->cref_stack; cref->nd_next = iseq->cref_stack;
iseq->cref_stack = cref; iseq->cref_stack = cref;
@ -214,7 +214,7 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
} }
else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) { else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
iseq->cref_stack = NEW_CREF(0); /* place holder */ iseq->cref_stack = NEW_CREF(0); /* place holder */
iseq->cref_stack->nd_omod = Qnil; iseq->cref_stack->nd_refinements = Qnil;
} }
else if (RTEST(parent)) { else if (RTEST(parent)) {
rb_iseq_t *piseq; rb_iseq_t *piseq;
@ -1657,7 +1657,7 @@ rb_iseq_clone(VALUE iseqval, VALUE newcbase)
} }
if (newcbase) { if (newcbase) {
iseq1->cref_stack = NEW_CREF(newcbase); iseq1->cref_stack = NEW_CREF(newcbase);
iseq1->cref_stack->nd_omod = iseq0->cref_stack->nd_omod; iseq1->cref_stack->nd_refinements = iseq0->cref_stack->nd_refinements;
iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi; iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi;
if (iseq0->cref_stack->nd_next) { if (iseq0->cref_stack->nd_next) {
iseq1->cref_stack->nd_next = iseq0->cref_stack->nd_next; iseq1->cref_stack->nd_next = iseq0->cref_stack->nd_next;

View file

@ -91,8 +91,8 @@ void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc,
rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex); rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex);
rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr); rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_get_with_omod(VALUE omod, VALUE klass, ID id, VALUE *define_class_ptr); rb_method_entry_t *rb_method_entry_get_with_refinements(VALUE refinements, VALUE klass, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, VALUE omod, ID id, VALUE *define_class_ptr); rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, VALUE refinements, ID id, VALUE *define_class_ptr);
rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex); rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex);
int rb_method_entry_arity(const rb_method_entry_t *me); int rb_method_entry_arity(const rb_method_entry_t *me);

2
node.h
View file

@ -281,7 +281,7 @@ typedef struct RNode {
#define nd_set_line(n,l) \ #define nd_set_line(n,l) \
RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT)) RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))
#define nd_omod nd_reserved #define nd_refinements nd_reserved
#define nd_head u1.node #define nd_head u1.node
#define nd_alen u2.argc #define nd_alen u2.argc

View file

@ -385,7 +385,8 @@ rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr)
rb_id2name(mid), type, (void *)recv, flags, klass); rb_id2name(mid), type, (void *)recv, flags, klass);
} }
} }
return rb_method_entry_get_with_omod(Qnil, klass, mid, defined_class_ptr); return rb_method_entry_get_with_refinements(Qnil, klass, mid,
defined_class_ptr);
} }
static inline int static inline int

View file

@ -1140,7 +1140,7 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
{ {
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp); rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
NODE *cref = NEW_CREF(klass); NODE *cref = NEW_CREF(klass);
cref->nd_omod = Qnil; cref->nd_refinements = Qnil;
cref->nd_visi = noex; cref->nd_visi = noex;
if (blockptr) { if (blockptr) {
@ -1151,7 +1151,7 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
} }
/* TODO: why cref->nd_next is 1? */ /* TODO: why cref->nd_next is 1? */
if (cref->nd_next && cref->nd_next != (void *) 1 && if (cref->nd_next && cref->nd_next != (void *) 1 &&
!NIL_P(cref->nd_next->nd_omod)) { !NIL_P(cref->nd_next->nd_refinements)) {
COPY_CREF_OMOD(cref, cref->nd_next); COPY_CREF_OMOD(cref, cref->nd_next);
} }

View file

@ -171,8 +171,8 @@ enum vm_regan_acttype {
/**********************************************************/ /**********************************************************/
#define COPY_CREF_OMOD(c1, c2) do { \ #define COPY_CREF_OMOD(c1, c2) do { \
(c1)->nd_omod = (c2)->nd_omod; \ (c1)->nd_refinements = (c2)->nd_refinements; \
if (!NIL_P((c2)->nd_omod)) { \ if (!NIL_P((c2)->nd_refinements)) { \
(c1)->flags |= NODE_FL_CREF_OMOD_SHARED; \ (c1)->flags |= NODE_FL_CREF_OMOD_SHARED; \
(c2)->flags |= NODE_FL_CREF_OMOD_SHARED; \ (c2)->flags |= NODE_FL_CREF_OMOD_SHARED; \
} \ } \

View file

@ -21,7 +21,7 @@ struct cache_entry { /* method hash table. */
VALUE filled_version; /* filled state version */ VALUE filled_version; /* filled state version */
ID mid; /* method's id */ ID mid; /* method's id */
VALUE klass; /* receiver's class */ VALUE klass; /* receiver's class */
VALUE omod; /* overlay modules */ VALUE refinements; /* refinements */
rb_method_entry_t *me; rb_method_entry_t *me;
VALUE defined_class; VALUE defined_class;
}; };
@ -405,16 +405,17 @@ lookup_method_table(VALUE klass, ID id, st_data_t *body)
} }
static inline rb_method_entry_t* static inline rb_method_entry_t*
search_method_with_omod(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr) search_method_with_refinements(VALUE klass, ID id, VALUE refinements,
VALUE *defined_class_ptr)
{ {
st_data_t body; st_data_t body;
VALUE iclass, skipped_class = Qnil; VALUE iclass, skipped_class = Qnil;
for (body = 0; klass; klass = RCLASS_SUPER(klass)) { for (body = 0; klass; klass = RCLASS_SUPER(klass)) {
if (klass != skipped_class) { if (klass != skipped_class) {
iclass = rb_hash_lookup(omod, klass); iclass = rb_hash_lookup(refinements, klass);
if (NIL_P(iclass) && BUILTIN_TYPE(klass) == T_ICLASS) { if (NIL_P(iclass) && BUILTIN_TYPE(klass) == T_ICLASS) {
iclass = rb_hash_lookup(omod, RBASIC(klass)->klass); iclass = rb_hash_lookup(refinements, RBASIC(klass)->klass);
if (!NIL_P(iclass)) if (!NIL_P(iclass))
iclass = copy_refinement_iclass(iclass, klass); iclass = copy_refinement_iclass(iclass, klass);
} }
@ -432,7 +433,7 @@ search_method_with_omod(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr
} }
static inline rb_method_entry_t* static inline rb_method_entry_t*
search_method_without_omod(VALUE klass, ID id, VALUE *defined_class_ptr) search_method_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
{ {
st_data_t body; st_data_t body;
@ -446,13 +447,14 @@ search_method_without_omod(VALUE klass, ID id, VALUE *defined_class_ptr)
} }
static rb_method_entry_t* static rb_method_entry_t*
search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr) search_method(VALUE klass, ID id, VALUE refinements, VALUE *defined_class_ptr)
{ {
if (NIL_P(omod)) { if (NIL_P(refinements)) {
return search_method_without_omod(klass, id, defined_class_ptr); return search_method_without_refinements(klass, id, defined_class_ptr);
} }
else { else {
return search_method_with_omod(klass, id, omod, defined_class_ptr); return search_method_with_refinements(klass, id, refinements,
defined_class_ptr);
} }
} }
@ -463,18 +465,19 @@ search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
* rb_method_entry() simply. * rb_method_entry() simply.
*/ */
rb_method_entry_t * rb_method_entry_t *
rb_method_entry_get_without_cache(VALUE klass, VALUE omod, ID id, rb_method_entry_get_without_cache(VALUE klass, VALUE refinements, ID id,
VALUE *defined_class_ptr) VALUE *defined_class_ptr)
{ {
VALUE defined_class; VALUE defined_class;
rb_method_entry_t *me = search_method(klass, id, omod, &defined_class); rb_method_entry_t *me = search_method(klass, id, refinements,
&defined_class);
if (ruby_running) { if (ruby_running) {
struct cache_entry *ent; struct cache_entry *ent;
ent = cache + EXPR1(klass, omod, id); ent = cache + EXPR1(klass, refinements, id);
ent->filled_version = GET_VM_STATE_VERSION(); ent->filled_version = GET_VM_STATE_VERSION();
ent->klass = klass; ent->klass = klass;
ent->omod = omod; ent->refinements = refinements;
ent->defined_class = defined_class; ent->defined_class = defined_class;
if (UNDEFINED_METHOD_ENTRY_P(me)) { if (UNDEFINED_METHOD_ENTRY_P(me)) {
@ -494,22 +497,23 @@ rb_method_entry_get_without_cache(VALUE klass, VALUE omod, ID id,
} }
rb_method_entry_t * rb_method_entry_t *
rb_method_entry_get_with_omod(VALUE omod, VALUE klass, ID id, rb_method_entry_get_with_refinements(VALUE refinements, VALUE klass, ID id,
VALUE *defined_class_ptr) VALUE *defined_class_ptr)
{ {
#if OPT_GLOBAL_METHOD_CACHE #if OPT_GLOBAL_METHOD_CACHE
struct cache_entry *ent; struct cache_entry *ent;
ent = cache + EXPR1(klass, omod, id); ent = cache + EXPR1(klass, refinements, id);
if (ent->filled_version == GET_VM_STATE_VERSION() && if (ent->filled_version == GET_VM_STATE_VERSION() &&
ent->mid == id && ent->klass == klass && ent->omod == omod) { ent->mid == id && ent->klass == klass &&
ent->refinements == refinements) {
if (defined_class_ptr) if (defined_class_ptr)
*defined_class_ptr = ent->defined_class; *defined_class_ptr = ent->defined_class;
return ent->me; return ent->me;
} }
#endif #endif
return rb_method_entry_get_without_cache(klass, omod, id, return rb_method_entry_get_without_cache(klass, refinements, id,
defined_class_ptr); defined_class_ptr);
} }
@ -517,12 +521,13 @@ rb_method_entry_t *
rb_method_entry(VALUE klass, ID id, VALUE *defined_class_ptr) rb_method_entry(VALUE klass, ID id, VALUE *defined_class_ptr)
{ {
NODE *cref = rb_vm_cref(); NODE *cref = rb_vm_cref();
VALUE omod = Qnil; VALUE refinements = Qnil;
if (cref && !NIL_P(cref->nd_omod)) { if (cref && !NIL_P(cref->nd_refinements)) {
omod = cref->nd_omod; refinements = cref->nd_refinements;
} }
return rb_method_entry_get_with_omod(omod, klass, id, defined_class_ptr); return rb_method_entry_get_with_refinements(refinements, klass, id,
defined_class_ptr);
} }
static void static void
@ -712,8 +717,8 @@ rb_undef(VALUE klass, ID id)
{ {
rb_method_entry_t *me; rb_method_entry_t *me;
NODE *cref = rb_vm_cref(); NODE *cref = rb_vm_cref();
VALUE omod = Qnil; VALUE refinements = Qnil;
void rb_overlay_module(NODE *cref, VALUE klass, VALUE module); void rb_using_refinement(NODE *cref, VALUE klass, VALUE module);
if (NIL_P(klass)) { if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class to undef method"); rb_raise(rb_eTypeError, "no class to undef method");
@ -729,10 +734,10 @@ rb_undef(VALUE klass, ID id)
rb_warn("undefining `%s' may cause serious problems", rb_id2name(id)); rb_warn("undefining `%s' may cause serious problems", rb_id2name(id));
} }
if (cref && !NIL_P(cref->nd_omod)) { if (cref && !NIL_P(cref->nd_refinements)) {
omod = cref->nd_omod; refinements = cref->nd_refinements;
} }
me = search_method(klass, id, omod, 0); me = search_method(klass, id, refinements, 0);
if (UNDEFINED_METHOD_ENTRY_P(me)) { if (UNDEFINED_METHOD_ENTRY_P(me)) {
const char *s0 = " class"; const char *s0 = " class";
@ -755,7 +760,7 @@ rb_undef(VALUE klass, ID id)
if (!RTEST(rb_class_inherited_p(klass, me->klass))) { if (!RTEST(rb_class_inherited_p(klass, me->klass))) {
VALUE mod = rb_module_new(); VALUE mod = rb_module_new();
rb_overlay_module(cref, klass, mod); rb_using_refinement(cref, klass, mod);
klass = mod; klass = mod;
} }
rb_add_method(klass, id, VM_METHOD_TYPE_UNDEF, 0, NOEX_PUBLIC); rb_add_method(klass, id, VM_METHOD_TYPE_UNDEF, 0, NOEX_PUBLIC);