summaryrefslogtreecommitdiff
path: root/test/ruby/test_variable.rb
diff options
context:
space:
mode:
authorKoichi Sasada <[email protected]>2023-02-10 16:02:20 +0900
committerKoichi Sasada <[email protected]>2023-02-10 17:55:25 +0900
commitbe94808282e50d3ecaa1392ffc38c9ec89e3438b (patch)
treef1e98d44d7743ce8785ac257282ba8082f831bd5 /test/ruby/test_variable.rb
parent38ecf08ba16b7e8946ac414f4f8c7ee155b34083 (diff)
use correct svar even if env is escaped
This patch is follo-up of 0a82bfe. Without this patch, if env is escaped (Proc'ed), strange svar can be touched. This patch tracks escaped env and use it.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7282
Diffstat (limited to 'test/ruby/test_variable.rb')
-rw-r--r--test/ruby/test_variable.rb78
1 files changed, 78 insertions, 0 deletions
diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb
index b7892f0cdc..1158313776 100644
--- a/test/ruby/test_variable.rb
+++ b/test/ruby/test_variable.rb
@@ -253,6 +253,84 @@ class TestVariable < Test::Unit::TestCase
assert_include(gv, :$12)
end
+ def prepare_klass_for_test_svar_with_ifunc
+ Class.new do
+ include Enumerable
+ def each(&b)
+ @b = b
+ end
+
+ def check1
+ check2.merge({check1: $1})
+ end
+
+ def check2
+ @b.call('foo')
+ {check2: $1}
+ end
+ end
+ end
+
+ def test_svar_with_ifunc
+ c = prepare_klass_for_test_svar_with_ifunc
+
+ expected_check1_result = {
+ check1: nil, check2: nil
+ }.freeze
+
+ obj = c.new
+ result = nil
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ assert_equal nil, result
+ assert_equal nil, $1
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+
+ # this frame was escaped so try it again
+ $~ = nil
+ obj = c.new
+ result = nil
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ assert_equal nil, result
+ assert_equal nil, $1
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+
+ # different context
+ result = nil
+ Fiber.new{
+ obj = c.new
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ }.resume # obj is created in antoher Fiber
+ assert_equal nil, result
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+
+ # different thread context
+ result = nil
+ Thread.new{
+ obj = c.new
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ }.join # obj is created in another Thread
+
+ assert_equal nil, result
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+ end
+
+
def test_global_variable_0
assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
end