Issue #16448 has been updated by mame (Yusuke Endoh).


`$~` is not a global variable, but a kind of local variable.  `String#gsub` assigns the match data to `$~` of its caller.  `data.gsub(/test/, &f1)` assigns `$~` of the scope of `check`.  The lambda `f1` reads `$~` of the toplevel scope, which is not set.

You can see the behavior by the following code:

```ruby
def check(f1)
  data = "foobar"

  data.gsub(/foo/, &f1) #=> #<MatchData "DUMMY">
  p $~                  #=> #<MatchData "foo">

  f2 = ->(match) { p $~ }

  data.gsub(/bar/, &f2) #=> #<MatchData "bar">
  p $~                  #=> #<MatchData "bar">
end

"DUMMY" =~ /DUMMY/
check(->(match) { p $~ })
```

----------------------------------------
Bug #16448: regex global variables are working differently depend on scope
https://bugs.ruby-lang.org/issues/16448#change-83352

* Author: tdrive (ѧߧڧݧѧ sdfsdfdsfs)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
Hi, everyone.

I am trying to write a code similar on this

``` ruby
#!/usr/bin/env ruby

def check(f1)
  f2 = ->(match) { p match; p $~ }
  
  data = "hello test test test"
  
  data.gsub(/test/, &f1)
  data.gsub(/test/, &f2)
end

check(->(match) { p match; p $~ })
```

output:
```
"test"
nil
"test"
nil
"test"
nil
"test"
#<MatchData "test">
"test"
#<MatchData "test">
"test"
#<MatchData "test">
```

ruby versions:
`ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]`
`ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin18]`


Why the global variable (`$~`) in f1 and f2 are working differently? It's a bug or my mistake?




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>