On Mon, Nov 22, 2010 at 3:53 PM, Robert Klemme
<shortcutter / googlemail.com> wrote:
> On Mon, Nov 22, 2010 at 1:28 PM, Ammar Ali <ammarabuali / gmail.com> wrote:
>>
>> Actually, 3 backslashes will yield one backslash. The first two result
>> in one (escaped), and the third one, escaped by the previous escaped
>> backslash ends up being one. My second example showed this, using 6
>> backslashes instead of 8. Using 4 backslashes works because the second
>> pair yields and escaped backslash, but it is not necessary.
>
> That does not work reliably under all circumstances though:
>
> irb(main):006:0> "abc".gsub /./, "\\\n"
> => "\\\n\\\n\\\n"
> irb(main):007:0> puts("abc".gsub /./, "\\\n")
> \
> \
> \
> => nil
> irb(main):008:0> "abc".gsub /./, "\\\\n"
> => "\\n\\n\\n"
> irb(main):009:0> puts("abc".gsub /./, "\\\\n")
> \n\n\n
> => nil

I think these examples are somewhat misleading, because the escaped
newline (\n) normally includes a backslash. Taking that into account,
i.e. not counting the one that is part of newline character, the first
example is only using 2 backslashes, and the second example is using
3. The same goes for its friends, \a, \r, \f, etc.

> It is safer to use 4 backslashes. This is the only robust way to do
> this even though sometimes you can simply use a single backslash (e.g.
> \1 instead of \\1) because string parsing is a bit tolerant under some
> circumstances:

I don't think this is tolerance from the string parser, it is
recognition of the \1 as a valid octal value.

> irb(main):014:0> '\1'
> => "\\1"
> irb(main):015:0> '\\1'
> => "\\1"

Here the single quotes are coming into play. Octal escapes are not
recognized within them. But it outputs the string in double quotes,
"forcing" the backslash to be escaped in the output. Backslashes need
to be escaped in single quoted string, just like they do in double
quoted ones, so in the second example ('\\1'), it's just one
backslash, again.

> but
>
> irb(main):019:0> "\n"
> => "\n"
> irb(main):020:0> "\\n"
> => "\\n"
> irb(main):021:0> "\1"
> => "\x01"
> irb(main):022:0> "\\1"
> => "\\1"

Here the double quotes are taking effect. The first correctly prints a
newline, the second an escaped one, the third gets recognized as an
octal escape, and the last escapes the meaning of the backslash that
would otherwise cause the 1 to be interpreted as an octal value.

Maybe using 4 backslashes is safer, overall, but I wouldn't make it a
rule. At least not without explaining these special cases that include
a leading backslash in their normal representation.

Regards,
Ammar