Search code examples
coercionraku

Perl6 string coercion operator ~ doesn't like leading zeros


I'm toying with Rakudo Star 2015.09.

If I try to stringify an integer with a leading zero, the compiler issues a warning:

> say (~01234).WHAT
Potential difficulties:
    Leading 0 does not indicate octal in Perl 6.
    Please use 0o123 if you mean that.
    at <unknown file>:1
    ------> say (~0123<HERE>).WHAT
(Str)

I thought maybe I could help the compiler by assigning the integer value to a variable, but obtained the same result:

> my $x = 01234; say (~$x).WHAT
Potential difficulties:
    Leading 0 does not indicate octal in Perl 6.
    Please use 0o1234 if you mean that.
    at <unknown file>:1
    ------> my $x = 01234<HERE>; say (~$x).WHAT
(Str)

I know this is a silly example, but is this by design? If so, why?

And how can I suppress this kind of warning message?


Solution

  • Is there a reason you have data with leading zeroes? I tend to run into this problem when I have a column of postal codes.

    When they were first thinking about Perl 6, one of the goals was to clean up some consistency issues. We had 0x and 0b (I think by that time), but Perl 5 still had to look for the leading 0 to guess it would be octal. See Radix Markers in Synopsis 2.

    But, Perl 6 also has to care about what Perl 5 programmers are going to try to do and what they expect. Most people are going to expect a leading 0 to mean octal. But, it doesn't mean octal. It's that you typed the literal, not how you are using it. Perl 6 has lots of warnings about things that Perl 5 people would try to use, like foreach:

    $ perl6 -e 'foreach @*ARGS -> $arg { say $arg }' 1 2 3
    ===SORRY!=== Error while compiling -e
    Unsupported use of 'foreach'; in Perl 6 please use 'for' at -e:1
    ------> foreach⏏ @*ARGS -> $arg { say $arg }
    

    To suppress that sort of warning, don't do what it's warning you about. The language doesn't want you to do that. If you need a string, start with a string '01234'. Or, if you want it to be octal, start with 0o. But, realize that stringifying a number will get you back the decimal representation:

    $ perl6 -e 'say ~0o1234'
    668