зеркало из https://github.com/github/ruby.git
* vm_eval.c (eval_string_with_cref): A binding should keep
refinements activation information and the refinements should be activated in subsequent eval calls with the binding. [ruby-core:67945] [Bug #10818] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49851 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
e5eb9a16df
Коммит
f403624a6f
|
@ -1,3 +1,10 @@
|
||||||
|
Thu Mar 5 11:50:54 2015 Shugo Maeda <shugo@ruby-lang.org>
|
||||||
|
|
||||||
|
* vm_eval.c (eval_string_with_cref): A binding should keep
|
||||||
|
refinements activation information and the refinements should be
|
||||||
|
activated in subsequent eval calls with the binding.
|
||||||
|
[ruby-core:67945] [Bug #10818]
|
||||||
|
|
||||||
Thu Mar 5 11:16:55 2015 Shugo Maeda <shugo@ruby-lang.org>
|
Thu Mar 5 11:16:55 2015 Shugo Maeda <shugo@ruby-lang.org>
|
||||||
|
|
||||||
* test/ruby/test_refinement.rb: There is no need anymore to supress
|
* test/ruby/test_refinement.rb: There is no need anymore to supress
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
|
|
||||||
class TestRefinement < Test::Unit::TestCase
|
class TestRefinement < Test::Unit::TestCase
|
||||||
|
module Sandbox
|
||||||
|
BINDING = binding
|
||||||
|
end
|
||||||
|
|
||||||
class Foo
|
class Foo
|
||||||
def x
|
def x
|
||||||
return "Foo#x"
|
return "Foo#x"
|
||||||
|
@ -65,7 +69,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
eval <<-EOF, TOPLEVEL_BINDING
|
eval <<-EOF, Sandbox::BINDING
|
||||||
using TestRefinement::FooExt
|
using TestRefinement::FooExt
|
||||||
|
|
||||||
class TestRefinement::FooExtClient
|
class TestRefinement::FooExtClient
|
||||||
|
@ -95,7 +99,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
eval <<-EOF, TOPLEVEL_BINDING
|
eval <<-EOF, Sandbox::BINDING
|
||||||
using TestRefinement::FooExt
|
using TestRefinement::FooExt
|
||||||
using TestRefinement::FooExt2
|
using TestRefinement::FooExt2
|
||||||
|
|
||||||
|
@ -411,7 +415,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_main_using_is_private
|
def test_main_using_is_private
|
||||||
assert_raise(NoMethodError) do
|
assert_raise(NoMethodError) do
|
||||||
eval("self.using Module.new", TOPLEVEL_BINDING)
|
eval("self.using Module.new", Sandbox::BINDING)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -426,7 +430,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_module_using_class
|
def test_module_using_class
|
||||||
assert_raise(TypeError) do
|
assert_raise(TypeError) do
|
||||||
eval("using TestRefinement::UsingClass", TOPLEVEL_BINDING)
|
eval("using TestRefinement::UsingClass", Sandbox::BINDING)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -587,7 +591,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_using_in_module
|
def test_using_in_module
|
||||||
assert_raise(RuntimeError) do
|
assert_raise(RuntimeError) do
|
||||||
eval(<<-EOF, TOPLEVEL_BINDING)
|
eval(<<-EOF, Sandbox::BINDING)
|
||||||
$main = self
|
$main = self
|
||||||
module M
|
module M
|
||||||
end
|
end
|
||||||
|
@ -600,14 +604,16 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_using_in_method
|
def test_using_in_method
|
||||||
assert_raise(RuntimeError) do
|
assert_raise(RuntimeError) do
|
||||||
eval(<<-EOF, TOPLEVEL_BINDING)
|
eval(<<-EOF, Sandbox::BINDING)
|
||||||
$main = self
|
$main = self
|
||||||
module M
|
module M
|
||||||
end
|
end
|
||||||
def call_using_in_method
|
class C
|
||||||
$main.send(:using, M)
|
def call_using_in_method
|
||||||
|
$main.send(:using, M)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
call_using_in_method
|
C.new.call_using_in_method
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -648,7 +654,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
eval <<-EOF, TOPLEVEL_BINDING
|
eval <<-EOF, Sandbox::BINDING
|
||||||
using TestRefinement::IncludeIntoRefinement::M
|
using TestRefinement::IncludeIntoRefinement::M
|
||||||
|
|
||||||
module TestRefinement::IncludeIntoRefinement::User
|
module TestRefinement::IncludeIntoRefinement::User
|
||||||
|
@ -711,7 +717,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
eval <<-EOF, TOPLEVEL_BINDING
|
eval <<-EOF, Sandbox::BINDING
|
||||||
using TestRefinement::PrependIntoRefinement::M
|
using TestRefinement::PrependIntoRefinement::M
|
||||||
|
|
||||||
module TestRefinement::PrependIntoRefinement::User
|
module TestRefinement::PrependIntoRefinement::User
|
||||||
|
@ -857,7 +863,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_module_using_invalid_self
|
def test_module_using_invalid_self
|
||||||
assert_raise(RuntimeError) do
|
assert_raise(RuntimeError) do
|
||||||
eval <<-EOF, TOPLEVEL_BINDING
|
eval <<-EOF, Sandbox::BINDING
|
||||||
module TestRefinement::TestModuleUsingInvalidSelf
|
module TestRefinement::TestModuleUsingInvalidSelf
|
||||||
Module.new.send(:using, TestRefinement::FooExt)
|
Module.new.send(:using, TestRefinement::FooExt)
|
||||||
end
|
end
|
||||||
|
@ -936,7 +942,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_eval_with_binding_scoping
|
def test_eval_with_binding_scoping
|
||||||
assert_in_out_err([], <<-INPUT, ["HELLO WORLD", "dlrow olleh", "HELLO WORLD"], [])
|
assert_in_out_err([], <<-INPUT, ["HELLO WORLD", "dlrow olleh", "dlrow olleh"], [])
|
||||||
module M
|
module M
|
||||||
refine String do
|
refine String do
|
||||||
def upcase
|
def upcase
|
||||||
|
@ -946,8 +952,9 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "hello world".upcase
|
puts "hello world".upcase
|
||||||
puts eval(%{using M; "hello world".upcase}, TOPLEVEL_BINDING)
|
b = binding
|
||||||
puts eval(%{"hello world".upcase}, TOPLEVEL_BINDING)
|
puts eval(%{using M; "hello world".upcase}, b)
|
||||||
|
puts eval(%{"hello world".upcase}, b)
|
||||||
INPUT
|
INPUT
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1424,6 +1431,6 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
private
|
private
|
||||||
|
|
||||||
def eval_using(mod, s)
|
def eval_using(mod, s)
|
||||||
eval("using #{mod}; #{s}", TOPLEVEL_BINDING)
|
eval("using #{mod}; #{s}", Sandbox::BINDING)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
13
vm_eval.c
13
vm_eval.c
|
@ -1304,10 +1304,15 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *const cref_arg,
|
||||||
th->parse_in_eval--;
|
th->parse_in_eval--;
|
||||||
|
|
||||||
if (!cref && base_block->iseq) {
|
if (!cref && base_block->iseq) {
|
||||||
orig_cref = rb_vm_get_cref(base_block->iseq, base_block->ep);
|
if (NIL_P(scope)) {
|
||||||
cref = NEW_CREF(Qnil);
|
orig_cref = rb_vm_get_cref(base_block->iseq, base_block->ep);
|
||||||
crefval = (VALUE) cref;
|
cref = NEW_CREF(Qnil);
|
||||||
COPY_CREF(cref, orig_cref);
|
crefval = (VALUE) cref;
|
||||||
|
COPY_CREF(cref, orig_cref);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cref = rb_vm_get_cref(base_block->iseq, base_block->ep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vm_set_eval_stack(th, iseqval, cref, base_block);
|
vm_set_eval_stack(th, iseqval, cref, base_block);
|
||||||
th->cfp->klass = CLASS_OF(base_block->self);
|
th->cfp->klass = CLASS_OF(base_block->self);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче