aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-05 02:56:03 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-05 02:56:03 +0000
commitf403624a6fe18cc6c95a19871a2784327cb17a3c (patch)
treeee423e748129a6146db4672dbbad5779f12a5f16
parente5eb9a16dff5ab5efd838726cfd1ca89fbe68b4f (diff)
downloadruby-f403624a6fe18cc6c95a19871a2784327cb17a3c.tar.gz
* 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
-rw-r--r--ChangeLog7
-rw-r--r--test/ruby/test_refinement.rb39
-rw-r--r--vm_eval.c13
3 files changed, 39 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 4fe33a4e3a..35db628443 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* test/ruby/test_refinement.rb: There is no need anymore to supress
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index 0d949c272e..70cffa86f4 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -1,6 +1,10 @@
require 'test/unit'
class TestRefinement < Test::Unit::TestCase
+ module Sandbox
+ BINDING = binding
+ end
+
class Foo
def x
return "Foo#x"
@@ -65,7 +69,7 @@ class TestRefinement < Test::Unit::TestCase
end
end
- eval <<-EOF, TOPLEVEL_BINDING
+ eval <<-EOF, Sandbox::BINDING
using TestRefinement::FooExt
class TestRefinement::FooExtClient
@@ -95,7 +99,7 @@ class TestRefinement < Test::Unit::TestCase
end
EOF
- eval <<-EOF, TOPLEVEL_BINDING
+ eval <<-EOF, Sandbox::BINDING
using TestRefinement::FooExt
using TestRefinement::FooExt2
@@ -411,7 +415,7 @@ class TestRefinement < Test::Unit::TestCase
def test_main_using_is_private
assert_raise(NoMethodError) do
- eval("self.using Module.new", TOPLEVEL_BINDING)
+ eval("self.using Module.new", Sandbox::BINDING)
end
end
@@ -426,7 +430,7 @@ class TestRefinement < Test::Unit::TestCase
def test_module_using_class
assert_raise(TypeError) do
- eval("using TestRefinement::UsingClass", TOPLEVEL_BINDING)
+ eval("using TestRefinement::UsingClass", Sandbox::BINDING)
end
end
@@ -587,7 +591,7 @@ class TestRefinement < Test::Unit::TestCase
def test_using_in_module
assert_raise(RuntimeError) do
- eval(<<-EOF, TOPLEVEL_BINDING)
+ eval(<<-EOF, Sandbox::BINDING)
$main = self
module M
end
@@ -600,14 +604,16 @@ class TestRefinement < Test::Unit::TestCase
def test_using_in_method
assert_raise(RuntimeError) do
- eval(<<-EOF, TOPLEVEL_BINDING)
+ eval(<<-EOF, Sandbox::BINDING)
$main = self
module M
end
- def call_using_in_method
- $main.send(:using, M)
+ class C
+ def call_using_in_method
+ $main.send(:using, M)
+ end
end
- call_using_in_method
+ C.new.call_using_in_method
EOF
end
end
@@ -648,7 +654,7 @@ class TestRefinement < Test::Unit::TestCase
end
end
- eval <<-EOF, TOPLEVEL_BINDING
+ eval <<-EOF, Sandbox::BINDING
using TestRefinement::IncludeIntoRefinement::M
module TestRefinement::IncludeIntoRefinement::User
@@ -711,7 +717,7 @@ class TestRefinement < Test::Unit::TestCase
end
end
- eval <<-EOF, TOPLEVEL_BINDING
+ eval <<-EOF, Sandbox::BINDING
using TestRefinement::PrependIntoRefinement::M
module TestRefinement::PrependIntoRefinement::User
@@ -857,7 +863,7 @@ class TestRefinement < Test::Unit::TestCase
def test_module_using_invalid_self
assert_raise(RuntimeError) do
- eval <<-EOF, TOPLEVEL_BINDING
+ eval <<-EOF, Sandbox::BINDING
module TestRefinement::TestModuleUsingInvalidSelf
Module.new.send(:using, TestRefinement::FooExt)
end
@@ -936,7 +942,7 @@ class TestRefinement < Test::Unit::TestCase
end
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
refine String do
def upcase
@@ -946,8 +952,9 @@ class TestRefinement < Test::Unit::TestCase
end
puts "hello world".upcase
- puts eval(%{using M; "hello world".upcase}, TOPLEVEL_BINDING)
- puts eval(%{"hello world".upcase}, TOPLEVEL_BINDING)
+ b = binding
+ puts eval(%{using M; "hello world".upcase}, b)
+ puts eval(%{"hello world".upcase}, b)
INPUT
end
@@ -1424,6 +1431,6 @@ class TestRefinement < Test::Unit::TestCase
private
def eval_using(mod, s)
- eval("using #{mod}; #{s}", TOPLEVEL_BINDING)
+ eval("using #{mod}; #{s}", Sandbox::BINDING)
end
end
diff --git a/vm_eval.c b/vm_eval.c
index 8dd9653840..6eeee5f02e 100644
--- a/vm_eval.c
+++ b/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--;
if (!cref && base_block->iseq) {
- orig_cref = rb_vm_get_cref(base_block->iseq, base_block->ep);
- cref = NEW_CREF(Qnil);
- crefval = (VALUE) cref;
- COPY_CREF(cref, orig_cref);
+ if (NIL_P(scope)) {
+ orig_cref = rb_vm_get_cref(base_block->iseq, base_block->ep);
+ cref = NEW_CREF(Qnil);
+ 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);
th->cfp->klass = CLASS_OF(base_block->self);