Project

General

Profile

Actions

Bug #14364

open

Regexp last match variable in procs

Added by aardvark179 (Duncan MacGregor) almost 7 years ago. Updated about 1 year ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
[ruby-core:84893]
Tags:

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.


Related issues 2 (2 open0 closed)

Related to Ruby master - Bug #20807: String#gsub fails when called from string subclass with a block passedOpenActions
Is duplicate of Ruby master - Bug #8444: Regexp vars $~ and friends are not thread localAssignedko1 (Koichi Sasada)Actions

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)
Actions #2

Updated by jeremyevans0 (Jeremy Evans) about 5 years ago

  • Is duplicate of Bug #8444: Regexp vars $~ and friends are not thread local added
Actions #3

Updated by jemmai (Jemma Issroff) about 1 year ago

  • Status changed from Open to Closed
Actions #4

Updated by jemmai (Jemma Issroff) about 1 year ago

  • Status changed from Closed to Open
Actions #5

Updated by jeremyevans0 (Jeremy Evans) 3 days ago

  • Related to Bug #20807: String#gsub fails when called from string subclass with a block passed added
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0