
Issue #20807 has been reported by koilanetroc (Oleg Tolmashov). ---------------------------------------- Bug #20807: String#gsub fails when called from string subclass with a block passed https://bugs.ruby-lang.org/issues/20807 * Author: koilanetroc (Oleg Tolmashov) * Status: Open * ruby -v: ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- When `String#gsub` is called from a string subclass with a block, `Regexp.last_match` is nil, but passed block is executed. Here is example code: ```ruby def call_gsub(str) str.gsub(/%/) do puts "checking #{str.class}" puts "Special variable value: #{$&}" puts "Regexp.last_match = #{Regexp.last_match.inspect}\n\n" raise "Special variable $& is not assigned, but block is called" if $&.nil? end end class MyString < String def gsub(*args, &block) super(*args, &block) # just forward everything end end text = 'test%text_with_special_character' call_gsub(String.new(text)) # original string call_gsub(MyString.new(text)) # string subclass ``` Result: ``` checking String Special variable value: % Regexp.last_match = #<MatchData "%"> checking MyString Special variable value: Regexp.last_match = nil gsub_bug.rb:7:in `block in call_gsub': Special variable $& is not assigned, but block is called (RuntimeError) from gsub_bug.rb:13:in `gsub' from gsub_bug.rb:13:in `gsub' from gsub_bug.rb:2:in `call_gsub' from gsub_bug.rb:20:in `<main>' ``` I expect result to be the same for both classes since `MyString` just wraps the same method: ``` checking String Special variable value: % Regexp.last_match = #<MatchData "%"> checking MyString Special variable value: % Regexp.last_match = #<MatchData "%"> ``` Maybe there is something off with with control frame when params are forwarded? Thanks in advance! -- https://bugs.ruby-lang.org/