..gsub adds its own layer of escaping. \1 refers to the first match, \2 to the second and there is also stuff like \'. (In general those forms are equivalent to global variables. E.g. \1 => $1)
Because Ruby's String literals already have one level of escaping you have to escape everything two times which is confusing.
You can do the above like this:
"ab\\cd".gsub(/\\/) { "\\\\" } # replaces one slash with two
"ab\\cd".gsub(/\\/, "\\\\\\\\" } # same
Of course having that meta layer available can make sense when you don't want to use a block:
"foobar quxquv".gsub(/\w(\w+)/, "\\1") # or in most cases also
"foobar quxquv".gsub(/\w(\w+)/, '\1') # but note that
"foobar quxquv".gsub(/\w(\w+)/, '\\\\') # replace with one slash
Personally I'd like this mess to be fixed by using $ instead of \ for the escaping layer of .gsub. That would yield code like this:
"foobar quxquv".gsub(/\w(\w+)/, "$1")
"ab\\cd".gsub(/\\/, "\\\\")
"Give me $1".gsub("$1", "$$2") # dollar needs to be escaped, new case
I don't know if matz also thinks that the latter version would be better than the current one, but even if it is like that there's still the problem of compatibility...
> I'm probably being dense, but -
>
>>>"ab\\cd".gsub(/\\/, "\\\\")
Here's the details, this comes up frequently:
..gsub adds its own layer of escaping. \1 refers to the first match, \2
to the second and there is also stuff like \'. (In general those forms
are equivalent to global variables. E.g. \1 => $1)
Because Ruby's String literals already have one level of escaping you
have to escape everything two times which is confusing.
"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
news:357nbmF4j4bmmU1@individual.net...
Bill Kelly wrote:
> I'm probably being dense, but -
>
>>>"ab\\cd".gsub(/\\/, "\\\\")
Here's the details, this comes up frequently:
In fact we could make this thread sticky - if that were possible with news
and mail readers.
Just to add one point to your excellent explanation: Another source of
confusion in this context is irb which uses String#inspect which in turn
adds escaping again:
irb(main):001:0> s = "a\\b"
=> "a\\b"
irb(main):002:0> puts s
a\b
=> nil