Gsub producing different results running the same code

Variables like $1 are populated after a regex match is performed. Simplifying your example a little:

s.gsub('original(value)', "replacement#{$1}")

The "replacement#{$1}" expression is evaluated before the gsub function is called. So $1 will be leftover from some previous regex task. (That’s why your second attempt works - it takes $1 from the first attempt)

There are a couple of options to solve this problem. gsub has lots of different functionalities.

My preference would be to pass a block to gsub. The block is evaluated after the regex has been matched, so $1 will work as you expect:

s.gsub('original(value)') { |match| "replacement#{$1}" }

Or you can use the ‘backreference’ feature of gsub. I’m not a fan of this syntax, but it does work. Rather than using "replacement#{$1}", you use 'replacement\1' (or \2, or \3, etc.)

s.gsub('original(value)', 'replacement\1')