* 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:
shugo 2015-03-05 02:56:03 +00:00
Родитель e5eb9a16df
Коммит f403624a6f
3 изменённых файлов: 39 добавлений и 20 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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);