14

I noticed while experimenting with tr///, that it doesn't seem to translate backslashes, even when escaped. For example,

say TR"\^/v"." given 'v^/\\';
say TR"\\^/v"." given 'v^/\\';
say TR"\ ^/v"." given 'v^/\\';

All of them output ...\ rather than what I expected, ....

There's some other weird behaviour too, like \ seemingly only escaping lowercase letters, but the docs page doesn't have much information... What exactly is the behaviour of backslashes (\) in transliteration (tr///)?

ugexe
  • 5,297
  • 1
  • 28
  • 49
Jo King
  • 590
  • 3
  • 17
  • I don't think any of the user doc aspects of [this gist](https://gist.github.com/raiph/a9d58825662b5cf2da2cc550cb3c6989) helps but perhaps the links to roast tests and code at the end do – raiph Oct 26 '18 at 19:19
  • 1
    It appears to me like a bug in the undocumented 'cc' role in QGrammar that gets used by the tr/// operator https://github.com/rakudo/rakudo/blob/master/src/Perl6/Grammar.nqp#L5333 – donaldh Oct 29 '18 at 22:43

2 Answers2

6

There is a bug caused by backslashes getting swallowed instead of correctly escaping things in the grammar for tr///.

say TR/\\// given '\\'
===SORRY!=== Error while compiling:
Malformed replacement part; couldn't find final /
at line 2
------> <BOL>⏏<EOL>

I have raised https://github.com/rakudo/rakudo/issues/2456 and submitted https://github.com/rakudo/rakudo/pull/2457 which fixes it.

The second part of the answer is that Perl 6 tries quite hard in some quoting constructs to only interpret \ as an escape for valid escape sequences, i.e. \n, \r, \s, \', etc. Otherwise it is left as a literal \.

donaldh
  • 833
  • 1
  • 8
  • 14
3

I do not have an explanation for the observed problem. However, when you use the Perl 6 Str.trans method it looks like it's working as expected:

say 'v^/\\'.trans( "\\^/v" => "." );

Outputs:

....

Reference:

raiph
  • 31,607
  • 3
  • 62
  • 111
wp78de
  • 18,207
  • 7
  • 43
  • 71
  • 3
    I know about the `trans` routine (I could even use `s:g///` if I wanted to be more regexey), but my question is specifically regarding the behaviour of `tr///`. `trans` simply takes `Pair`s, and the strings and regexes are evaluated on the usual way beforehand. – Jo King Oct 27 '18 at 01:41