Bug #14364
openRegexp last match variable in procs
Description
While working on TruffleRuby's regexp variables implementation I found the following behaviour when comparing our behaviour with MRI 2.3.5 and 2.5.0.
Some core methods such as String#scan
take an optional block argument, and if this is a literal block then each time it is yielded to the $~
variable will have been set. However, if the block is a proc that was not defined in the caller's scope then $~
does not appear to get set or is inaccessible.
The following test script demonstrates the problem.
class ScanChecker
def block
Proc.new do
puts "$~ is #{$~}"
end
end
end
puts 'Checking with literal block.'
'hello'.scan(/l/) do
puts "$~ is #{$~}"
end
puts 'Checking with a Proc from same scope'
my_proc = Proc.new do
puts "$~ is #{$~}"
end
'hello'.scan(/l/, &my_proc)
puts 'Checking with a Proc.'
checker = ScanChecker.new
'hello'.scan(/l/, &checker.block)
I would have expected the $~
to be set in all cases, but I'm not sure if that is the intended behaviour.
Updated by long_long_float (kazuki niimi) about 6 years ago
This may be a specification. This(it's written in japanese) page says $~
is local scope and thread local.
The following code describes this behavior. The a
can be referred at my_proc
, but it cannot be referrd at ScanChecker
(the initial value of $ ~
is nil).
a = 10
class ScanChecker
def block
Proc.new do
puts a # error
puts "$~ is #{$~}"
end
end
end
puts 'Checking with a Proc from same scope'
my_proc = Proc.new do
puts a # => 10
puts "$~ is #{$~}"
end
'hello'.scan(/l/, &my_proc)
puts 'Checking with a Proc.'
checker = ScanChecker.new
'hello'.scan(/l/, &checker.block)
Updated by jeremyevans0 (Jeremy Evans) about 5 years ago
- Is duplicate of Bug #8444: Regexp vars $~ and friends are not thread local added
Updated by jemmai (Jemma Issroff) about 1 year ago
- Status changed from Open to Closed
Updated by jemmai (Jemma Issroff) about 1 year ago
- Status changed from Closed to Open
Updated by jeremyevans0 (Jeremy Evans) 4 days ago
- Related to Bug #20807: String#gsub fails when called from string subclass with a block passed added