* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
039e2a35c2
commit
0954607864
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
Sat Sep 29 11:21:06 2012 Shugo Maeda <shugo@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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 <h.shirosaki@gmail.com>
|
Sat Sep 29 02:18:57 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
|
||||||
|
|
||||||
* test/ruby/test_unicode_escape.rb (TestUnicodeEscape#test_basic):
|
* test/ruby/test_unicode_escape.rb (TestUnicodeEscape#test_basic):
|
||||||
|
4
eval.c
4
eval.c
@ -1096,7 +1096,7 @@ rb_using_module(NODE *cref, VALUE module)
|
|||||||
ID id_overlaid_modules;
|
ID id_overlaid_modules;
|
||||||
VALUE overlaid_modules;
|
VALUE overlaid_modules;
|
||||||
|
|
||||||
Check_Type(module, T_MODULE);
|
check_class_or_module(module);
|
||||||
CONST_ID(id_overlaid_modules, "__overlaid_modules__");
|
CONST_ID(id_overlaid_modules, "__overlaid_modules__");
|
||||||
overlaid_modules = rb_attr_get(module, id_overlaid_modules);
|
overlaid_modules = rb_attr_get(module, id_overlaid_modules);
|
||||||
if (NIL_P(overlaid_modules)) return;
|
if (NIL_P(overlaid_modules)) return;
|
||||||
@ -1117,6 +1117,7 @@ rb_mod_using(VALUE self, VALUE module)
|
|||||||
ID id_using_modules;
|
ID id_using_modules;
|
||||||
VALUE using_modules;
|
VALUE using_modules;
|
||||||
|
|
||||||
|
Check_Type(module, T_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)) {
|
||||||
@ -1345,6 +1346,7 @@ f_using(VALUE self, VALUE module)
|
|||||||
{
|
{
|
||||||
NODE *cref = rb_vm_cref();
|
NODE *cref = rb_vm_cref();
|
||||||
|
|
||||||
|
Check_Type(module, T_MODULE);
|
||||||
rb_using_module(cref, module);
|
rb_using_module(cref, module);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -361,6 +361,34 @@ class TestRefinement < Test::Unit::TestCase
|
|||||||
assert_equal([:m1, :m2], m2.module_eval { obj.foo })
|
assert_equal([:m1, :m2], m2.module_eval { obj.foo })
|
||||||
end
|
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
|
def test_refine_module_and_call_superclass_method
|
||||||
m1 = Module.new
|
m1 = Module.new
|
||||||
c1 = Class.new {
|
c1 = Class.new {
|
||||||
@ -399,4 +427,32 @@ class TestRefinement < Test::Unit::TestCase
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
@ -1830,27 +1830,22 @@ rb_vm_using_modules(NODE *cref, VALUE klass)
|
|||||||
ID id_using_modules;
|
ID id_using_modules;
|
||||||
VALUE using_modules;
|
VALUE using_modules;
|
||||||
|
|
||||||
|
if (NIL_P(klass)) return;
|
||||||
CONST_ID(id_using_modules, "__using_modules__");
|
CONST_ID(id_using_modules, "__using_modules__");
|
||||||
using_modules = rb_attr_get(klass, id_using_modules);
|
using_modules = rb_attr_get(klass, id_using_modules);
|
||||||
switch (TYPE(klass)) {
|
if (NIL_P(using_modules) && BUILTIN_TYPE(klass) == T_CLASS) {
|
||||||
case T_CLASS:
|
VALUE super = rb_class_real(RCLASS_SUPER(klass));
|
||||||
if (NIL_P(using_modules)) {
|
using_modules = rb_attr_get(super, id_using_modules);
|
||||||
VALUE super = rb_class_real(RCLASS_SUPER(klass));
|
if (!NIL_P(using_modules)) {
|
||||||
using_modules = rb_attr_get(super, id_using_modules);
|
using_modules = rb_hash_dup(using_modules);
|
||||||
if (!NIL_P(using_modules)) {
|
rb_ivar_set(klass, id_using_modules, 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)) {
|
if (!NIL_P(using_modules)) {
|
||||||
rb_hash_foreach(using_modules, vm_using_module_i,
|
rb_hash_foreach(using_modules, vm_using_module_i,
|
||||||
(VALUE) cref);
|
(VALUE) cref);
|
||||||
}
|
}
|
||||||
|
rb_using_module(cref, klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user