Skip to content

Commit

Permalink
* vm_insnhelper.c (rb_vm_using_modules): use using_modules before
Browse files Browse the repository at this point in the history
  klass to fix method lookup order, and use klass even if klass is
  not a module to make refinements in class_eval invoked on classes
  work.

* eval.c (rb_using_module): accept a class as the second argument.

* eval.c (rb_mod_using, f_using): raise a TypeError if the argument
  is not a module.

* test/ruby/test_refinement.rb: add new tests for the above changes.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
shugo committed Sep 29, 2012
1 parent 039e2a3 commit 0954607
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 14 deletions.
14 changes: 14 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
Sat Sep 29 11:21:06 2012 Shugo Maeda <[email protected]>

* vm_insnhelper.c (rb_vm_using_modules): use using_modules before
klass to fix method lookup order, and use klass even if klass is
not a module to make refinements in class_eval invoked on classes
work.

* eval.c (rb_using_module): accept a class as the second argument.

* eval.c (rb_mod_using, f_using): raise a TypeError if the argument
is not a module.

* test/ruby/test_refinement.rb: add new tests for the above changes.

Sat Sep 29 02:18:57 2012 Hiroshi Shirosaki <[email protected]>

* test/ruby/test_unicode_escape.rb (TestUnicodeEscape#test_basic):
Expand Down
4 changes: 3 additions & 1 deletion eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,7 @@ rb_using_module(NODE *cref, VALUE module)
ID id_overlaid_modules;
VALUE overlaid_modules;

Check_Type(module, T_MODULE);
check_class_or_module(module);
CONST_ID(id_overlaid_modules, "__overlaid_modules__");
overlaid_modules = rb_attr_get(module, id_overlaid_modules);
if (NIL_P(overlaid_modules)) return;
Expand All @@ -1117,6 +1117,7 @@ rb_mod_using(VALUE self, VALUE module)
ID id_using_modules;
VALUE using_modules;

Check_Type(module, T_MODULE);
CONST_ID(id_using_modules, "__using_modules__");
using_modules = rb_attr_get(self, id_using_modules);
if (NIL_P(using_modules)) {
Expand Down Expand Up @@ -1345,6 +1346,7 @@ f_using(VALUE self, VALUE module)
{
NODE *cref = rb_vm_cref();

Check_Type(module, T_MODULE);
rb_using_module(cref, module);
return self;
}
Expand Down
56 changes: 56 additions & 0 deletions test/ruby/test_refinement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,34 @@ def foo
assert_equal([:m1, :m2], m2.module_eval { obj.foo })
end

def test_refine_module_with_double_overriding
m1 = Module.new {
def foo
[:m1]
end
}
c = Class.new {
include m1
}
m2 = Module.new {
refine m1 do
def foo
super << :m2
end
end
}
m3 = Module.new {
using m2
refine m1 do
def foo
super << :m3
end
end
}
obj = c.new
assert_equal([:m1, :m2, :m3], m3.module_eval { obj.foo })
end

def test_refine_module_and_call_superclass_method
m1 = Module.new
c1 = Class.new {
Expand Down Expand Up @@ -399,4 +427,32 @@ def test_refine_neither_class_nor_module
}
end
end

def test_refine_in_class_and_class_eval
c = Class.new {
refine Fixnum do
def foo
"c"
end
end
}
assert_equal("c", c.class_eval { 123.foo })
end

def test_kernel_using_class
c = Class.new
assert_raise(TypeError) do
using c
end
end

def test_module_using_class
c = Class.new
m = Module.new
assert_raise(TypeError) do
m.module_eval do
using c
end
end
end
end
21 changes: 8 additions & 13 deletions vm_insnhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1830,27 +1830,22 @@ rb_vm_using_modules(NODE *cref, VALUE klass)
ID id_using_modules;
VALUE using_modules;

if (NIL_P(klass)) return;
CONST_ID(id_using_modules, "__using_modules__");
using_modules = rb_attr_get(klass, id_using_modules);
switch (TYPE(klass)) {
case T_CLASS:
if (NIL_P(using_modules)) {
VALUE super = rb_class_real(RCLASS_SUPER(klass));
using_modules = rb_attr_get(super, id_using_modules);
if (!NIL_P(using_modules)) {
using_modules = rb_hash_dup(using_modules);
rb_ivar_set(klass, id_using_modules, using_modules);
}
if (NIL_P(using_modules) && BUILTIN_TYPE(klass) == T_CLASS) {
VALUE super = rb_class_real(RCLASS_SUPER(klass));
using_modules = rb_attr_get(super, id_using_modules);
if (!NIL_P(using_modules)) {
using_modules = rb_hash_dup(using_modules);
rb_ivar_set(klass, id_using_modules, using_modules);
}
break;
case T_MODULE:
rb_using_module(cref, klass);
break;
}
if (!NIL_P(using_modules)) {
rb_hash_foreach(using_modules, vm_using_module_i,
(VALUE) cref);
}
rb_using_module(cref, klass);
}

static VALUE
Expand Down

0 comments on commit 0954607

Please sign in to comment.