From: "Hanmac (Hans Mackowiak) via ruby-core" <ruby-core@...>
Date: 2025-01-15T14:50:35+00:00
Subject: [ruby-core:120698] [Ruby master Bug#21040] String#next! method does not mutate $& variable

Issue #21040 has been updated by Hanmac (Hans Mackowiak).


These are called `virtual variables`, a new object is created each time you try to access it

```c
    rb_define_virtual_variable("$~", get_LAST_MATCH_INFO, match_setter);
    rb_define_virtual_variable("$&", last_match_getter, 0);
    rb_define_virtual_variable("$`", prematch_getter, 0);
    rb_define_virtual_variable("$'", postmatch_getter, 0);
    rb_define_virtual_variable("$+", last_paren_match_getter, 0);
```

in ruby this is the result:
```ruby

"123".gsub(/.../){
  p [$&, 
     $&.object_id, #=> 30
     $&.object_id  #=> 40
  ]
}
```

----------------------------------------
Bug #21040: String#next! method does not mutate $& variable
https://bugs.ruby-lang.org/issues/21040#change-111533

* Author: radarek (Rados��aw Bu��at)
* Status: Rejected
* ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [arm64-darwin24]
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
`String#next!` method should mutate string and return mutated version. For some reason, using it on `$&` does not mutate it but still returns new version.

Steps to reproduce (2 different ways):


```ruby
"123".gsub(/./){$&.next!}    # returns "234" as expected
"123".gsub(/./){$&.next!;$&} # returns "123" but should be "234"
"123".gsub(/./){_1.next!;_1} # returns "234" as expected



"123"[/./]
puts $&.      # prints 1
puts $&.next! # prints 2
puts $&       # prints 1 but should be 2
```




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/