Strange behaviour on replacement String#gsub!

Hello guys. I’m going to throw this lines of code here, this is rare.
Anyone know why does this happens?

rb(main):016:0> a = ‘\\\’
=> “\\\”
irb(main):017:0> a.gsub!(/\\\/, ‘\\’)
=> “\”
irb(main):018:0> puts a

=> nil
irb(main):019:0> a = ‘\\\’
=> “\\\”
irb(main):020:0> a.gsub!(/\\\/, ‘\\\’)
=> “\\”
irb(main):021:0> puts a
\
=> nil

So as you can see, to make what I want to make, which is replace 3
for 2 \ I have to do a.gsub!(/\\\/, ‘\\\’) which is ironic because
both things(#RegExp and the #String) are the same. I also tried with
#String vs #String:

irb(main):030:0> a = ‘\\\’
=> “\\\”
irb(main):031:0> puts a
\
=> nil
irb(main):032:0> a.gsub!(’\\\’, ‘\\\’)
=> “\\”
irb(main):033:0> puts a
\

Can this be a bug of Ruby? I’m using 2.1.6. Cheers guys!

No, no bug there.
But the replacement string gets evaluated twice:
First as a string literal so ‘\\’ becomes \ . This string then gets
handed to the regex machine which searches this string for
group references. The escape character for this is also a backslash so
“\” becomes \ .

For String#gsub and the like you actually have to quadruple your
backslashes, so your replacement string should look like this:
‘\\\\’

‘\\\’ also works, but only because the regex engine gets ‘\’ as
input and has no escape candidate for the last backslash and then treats
it as a literal \ . It won’t work anymore if you put some of the special
characters (like &+'012 etc.) at the end of your replacement string.

Greetings,
daemor

Sascha A. wrote in post #1178317:

No, no bug there.
But the replacement string gets evaluated twice:
First as a string literal so ‘\\’ becomes \ . This string then gets
handed to the regex machine which searches this string for
group references. The escape character for this is also a backslash so
“\” becomes \ .

For String#gsub and the like you actually have to quadruple your
backslashes, so your replacement string should look like this:
‘\\\\’

‘\\\’ also works, but only because the regex engine gets ‘\’ as
input and has no escape candidate for the last backslash and then treats
it as a literal \ . It won’t work anymore if you put some of the special
characters (like &+'012 etc.) at the end of your replacement string.

Greetings,
daemor

Thanks for answering. That make sense sir, I didn’t realized that Ruby
make a pre-process on replacement string, you are right.