Operators in Perl to Raku: equivalencies and variations
A (hopefully) comprehensive list of Perl operators with their Raku equivalents with notes on variations between them where necessary.
This document does not explain the operators in detail. This document is an attempt to guide you from the operators in Perl's perlop
document to their equivalents in Raku. For full documentation on the Raku equivalents, please see the Raku documentation.
The operator precedence table is somewhat different in Raku than it is in Perl, so it will not be detailed here. If you need to know the precedence and associativity of a given operator in Raku, refer to Operator Precedence.
The things listed in Perl's perlop
document as unary and list operators in this section tend to be things that can also be thought of as functions, such as print
and chdir
. As such, you can find information about them in the functions guide. Parentheses are still used for grouping. There is one caveat: in Raku, it's the ,
(comma) that creates lists, not parentheses. So:
my = 1,2,3,4,5; # no parentheses needed.say for 1,2,3,4,5; # also no parenthesesmy = (1); # *not* a list, as there is no commamy = (1,); # a List in a scalar container
As you typically will not be using references in Raku, the arrow is probably less useful as a dereferencing operator. If you do need to dereference something, however, the arrow is the dot. It is also the dot for method calls. So, Perl's $arrayref->[7]
becomes $arrayref.[7]
in Raku and, similarly, $user->name
becomes $user.name
. The =>
arrow is used for constructing Pairs, see Pair term documentation.
Work as in Perl. The one possible caveat is that they function by calling the succ
method for ++
and the pred
method for --
. For builtin numeric types, this is unlikely to do something unusual, but custom types can define their own succ
and pred
methods, so in those cases, you should probably take note of what ++
and --
will actually do.
Works as you would expect. The caveat in Perl's perlop about **
binding more tightly than unary minus (i. e. "-2**4" evaluates as "-(2**4)" rather than "(-2)**4)") is also true for Raku.
As in Perl, unary !
and -
do logical and arithmetic negation, respectively. ?^
is used for bitwise logical negation, which the documentation indicates is equivalent to !
. It may be relevant to note that these coerce their arguments to Bool
and Numeric
, respectively.
Unary ~
is the string context operator in Raku, so use prefix +^
for bitwise integer negation. Assumes two's complement.
+
does have an effect in Raku, coercing its argument to the Numeric type.
Unary \
is no more. If you really want to take a "reference" to an existing named variable, you can use item context, like so: $aref = item(@array)
, or maybe more familiarly by prefixing with a $
: $aref = $@array
. Please note that you're not really getting a reference, but a scalar container with the referenced object in it.
You can get a "reference" to a named subroutine by using the &
sigil: $sref = &foo
. Anonymous arrays, hashes, and subs return the underlying object during creation right away: $sref = sub { }
.
=~
and !~
have been replaced by ~~
and !~~
, respectively. Those of you who consider smartmatching broken in Perl will be happy to hear that it works much better in Raku, as the stronger typing means less guesswork. See the smartmatch documentation for a more extensive explanation of how smartmatch works in Raku.
Binary *
, /
, and %
do multiplication, division, and modulo, respectively, as in Perl.
Binary x
is slightly different in Raku, and has a companion. print '-' x 80;
gives you a string of 80 dashes, but for the Perl behavior of @ones = (1) x 80;
giving you a list of 80 "1"s, you would use @ones = 1 xx 80;
.
Binary +
and -
do addition and subtraction, respectively, as you would expect.
As .
is the method call operator, so binary ~
acts as the concatenation operator in Raku.
<<
and >>
have been replaced by +<
and +>
.
As noted above, you'll find these in the functions guide.
These all work as in Perl.
==
and !=
both work as in Perl.
<=>
and cmp
have different behavior in Raku. <=>
does a numeric comparison, but returns Order::Less
, Order::Same
, or Order::More
instead of Perl's -1
, 0
, or 1
. To get the Perl behavior (with the change that it returns the Order
objects, rather than integers) of cmp
, you would use the leg
operator.
cmp
does either <=>
or leg
, depending on the existing type of its arguments.
~~
is the smartmatch operator as in Perl, but it's also just the match operator in Raku, as noted above. For how smartmatching works in Raku, see the smartmatch documentation.
See the smartmatch documentation for a more extensive explanation of how smartmatch works in Raku.
Binary &
is +&
in Raku.
Bitwise OR has changed from |
in Perl to +|
in Raku. Similarly, bitwise XOR ^
is +^
, except this operates on integers.
Unchanged.
Unchanged.
Remains in Raku as //
. Returns the first defined operand, or else the last operand. Also, there is a low precedence version, called orelse
.
In list context, ..
operates as the range operator and should not need to be changed. That said, there are exclusionary range operators that may be useful. These are:
infix ..^
which excludes the endpoint;
infix ^.. which excludes the starting point;
infix ^..^
which excludes both the starting and ending points;
prefix ^
which starts from zero excluding the endpoint.
The following example shows the effects of all the above range operators (please note parentheses are used only to allow the method call):
(1..^5).list; # (1 2 3 4)(1^..5).list; # (2 3 4 5)(1^..^5).list; # (2 3 4)(^5).list; # (0 1 2 3 4)
In Perl, in scalar context, the operators ..
and ...
work as flip-flop operators, even if they are little-known and probably less used. Those operators have been replaced in Raku by ff and fff respectively.
The conditional operator ? :
has been replaced by ?? !!
:
= ? : ; # Perl
= ?? !! ; # Raku
Although not fully documented, S03 indicates that the mathematical and logical assignment operators should work as you would expect. The one noticeable change is that .=
calls a mutating method on the object on the left (which can also be a type-object). This allows for the following useful idiom:
my LongClassName .= new( frobnicate => 42 ); # no need to repeat class name
This ensures that $bar
will only be able to contain a LongClassName
object, as well not having to repeat (and possibly misspell) the class name.
~=
is the string concatenation assignment, as you might expect with the changes in .
and ~
. Also, the bitwise assignment operators are likely not separated into numeric and string versions (&=
, etc., vs. &.=
, etc.), as that feature is currently experimental in Perl itself - although, again, this is not specifically documented.
The comma operator works mostly as expected, but technically it creates Lists) or separates arguments in function calls. Also, there is a :
variant that turns function calls into method calls - see this page.
The =>
operator, or fat arrow, works similarly to the Perl "fat comma" in that it allows an unquoted (ordinary) identifier on its left side, but in Raku constructs Pair objects, rather than just functioning as a separator. If you are trying to just literally translate a line of Perl code to Raku, it should behave as expected. To read Raku, take a look at Adverbial Pair which will explain a new syntax.
Like the Named Unary Operators, you'll find these discussed under functions.
The lower precedence version of !
. As with !
, coerces its argument to Bool
.
Lower precedence version of &&
as in Perl.
or
is the low precedence version of ||
, and xor
is the low precedence version of ^^
.
Additionally, there is a low precedence version of //
, called orelse
.
For all the gory details on quoting constructs, see quoting.
There is a quoting operator that allows absolute literal strings: Q
or 「…」
, although the latter might be difficult to find on your keyboard, depending on your keyboard... Backslash escapes do not apply in Q
quoted strings. E. g. Q{This is still a closing curly brace → \}
renders "This is still a closing curly brace → \".
q
does what you expect, allowing backslash escapes. E. g. q{This is not a closing curly brace → \}, but this is → }
returning "This is not a closing curly brace → }, but this is →". As in Perl, you can get this behavior with single quotes.
qq
allows interpolation of variables. However, by default, only scalar variables are interpolated. To get other variables to interpolate, you need to put square brackets after them (the so-called zen-slice) to get them to interpolate. E.g. @a = <1 2 3>; say qq/@a[] example@example.com/;
results in "1 2 3 example@example.com". Hashes interpolate in the same manner: %a = 1 => 2, 3 => 4;say "%a{}";
results in a space separating the pairs and tabs separating the key from the value in each pair (because that's the standard stringification of Pair
s, and a hash acts as list of Pair
s when stringified). You can also interpolate Raku code in strings using curly braces. For all the details, see Interpolation.
qw
works as in Perl, and can also be rendered as <...>
. E. g. qw/a b c/
is equivalent to <a b c>
.
There is also a version of qw
that interpolates, which is qqw
. So my $a = 42;say qqw/$a b c/;
gives you "42 b c".
Shell quoting is available through qx
, but you should note that backticks do not do shell quoting as in Perl, and Perl variables are not interpolated in qx
strings. If you need to interpolate Perl variables in a shell command string, you can use qqx
instead.
The qr
operator is gone from Raku.
tr///
works similarly to how it does in Perl. The one caveat is that ranges are specified differently. Instead of using a range "a-z", you would use "a..z", i. e. with Perl's range operator. tr///
has a method version, which is better documented, called .trans
. .trans
uses a list of pairs, as follows: $x.trans(['a'..'c'] => ['A'..'C'], ['d'..'q'] => ['D'..'Q'], ['r'..'z'] => ['R'..'Z']);
A much more extensive description of the uses of .trans
can be found at https://design.raku.org/S05.html#Transliteration. The y///
equivalent has been done away with.
Heredocs are specified differently in Raku. You use :to
with your quoting operator, e. g. q:to/END/;
would start a heredoc ending with "END". Similarly, you get escaping and interpolation based on your quoting operator, i. e. literals with Q
, backslash escapes with q
, and interpolation with qq
.
The full details on Input/Output in Raku can be found at io.
As <...>
is the quote-words construct in Raku, <>
is not used for reading lines from a file. You can do that by either making an IO
object from a file name or using an open filehandle and then, in either case, calling .lines
on it. I. e. either my @a = "filename".IO.lines;
or my $fh = open "filename", :r;my @a = $fh.lines;
(In the latter case, we are using :r
to specifically open the file for reading). To do this in an iterative manner, you can use a for
loop this way:
for 'huge-csv'.IO.lines ->
Note the use of ->
there. That's part of the Block syntax, and in Raku is needed for if
, for
, while
, etc.
If you want to slurp the entire file into a scalar, you would - surprise! - use the .slurp
method. For instance
my = "filename".IO.slurp;# ... or ...my = open "filename", :r;my = .slurp;
As noted in the Special Variables guide, the ARGV
magic input filehandle has been replaced by $*ARGFILES
, and the @ARGV
array of command line arguments has been replaced by @*ARGS
.
1 while foo();
works in the same way as it does in Perl, however it generates a warning. In Raku the idiom is now written as Nil while foo();
instead.
Documented individually above, but to summarize...
Bitwise integer negation is prefix +^
. Bitwise Boolean negation is ?^
.
Bitwise and is +&
.
Bitwise integer or is +|
. Bitwise integer xor is infix +^
. Bitwise Boolean or is ?|
.
Left shift and right shift are +<
and +>
.