PetaPerl implements the full set of Perl 5 operators with identical semantics. All operators maintain Perl’s context sensitivity and precedence rules.
| Operator | Operation | Example |
+ | Addition | $a + $b |
- | Subtraction | $a - $b |
* | Multiplication | $a * $b |
/ | Division | $a / $b |
% | Modulus | $a % $b |
** | Exponentiation | $a ** $b |
All arithmetic operators coerce operands to numeric context. Division by zero produces a warning and returns infinity or NaN.
my $x = 5 + 3; # 8
my $y = 10 / 3; # 3.333...
my $z = 2 ** 10; # 1024
my $m = 17 % 5; # 2
| Operator | Operation | Example |
. | Concatenation | $a . $b |
x | Repetition | $str x $count |
String operators coerce operands to string context.
my $str = "Hello" . " " . "World"; # "Hello World"
my $rep = "X" x 5; # "XXXXX"
my $pad = " " x 10; # 10 spaces
| Operator | Operation | Returns |
== | Equal | True if equal |
!= | Not equal | True if not equal |
< | Less than | True if less |
> | Greater than | True if greater |
<= | Less or equal | True if ≤ |
>= | Greater or equal | True if ≥ |
<=> | Three-way compare | -1, 0, or 1 |
Numeric comparisons coerce operands to numbers.
if ($age >= 18) { ... }
my $cmp = $a <=> $b; # -1 if $a < $b, 0 if equal, 1 if $a > $b
| Operator | Operation | Returns |
eq | Equal | True if equal |
ne | Not equal | True if not equal |
lt | Less than | True if less |
gt | Greater than | True if greater |
le | Less or equal | True if ≤ |
ge | Greater or equal | True if ≥ |
cmp | Three-way compare | -1, 0, or 1 |
String comparisons use lexicographic (dictionary) ordering.
if ($name eq "John") { ... }
my $cmp = $a cmp $b; # -1, 0, or 1
| Operator | Operation | Short-circuits | Precedence |
&& | And | Yes | High |
| ` | | ` | Or |
// | Defined-or | Yes | High |
and | And | Yes | Low |
or | Or | Yes | Low |
xor | Exclusive or | No | Low |
Logical operators return the last evaluated value, not just true/false.
my $result = $x && $y; # Returns $y if $x true, else $x
my $default = $user || "guest"; # Returns "guest" if $user false
my $value = $config // 0; # Returns 0 only if $config undefined
Defined-or (//): Unlike ||, this only checks if the left side is defined, not just true. 0 and "" are both false but defined.
my $x = 0;
my $a = $x || 10; # 10 (0 is false)
my $b = $x // 10; # 0 (0 is defined)
| Operator | Operation | Example |
& | Bitwise AND | $a & $b |
| ` | ` | Bitwise OR |
^ | Bitwise XOR | $a ^ $b |
<< | Left shift | $a << $n |
>> | Right shift | $a >> $n |
Bitwise operators work on integers. Operands are converted to unsigned integers.
my $mask = 0xFF & $value;
my $flags = $READ | $WRITE;
my $double = $x << 1;
| Operator | Operation | Context |
.. | Inclusive range | List context creates list |
... | Flip-flop | Scalar context is stateful |
my @digits = (0..9); # (0, 1, 2, ..., 9)
my @letters = ('a'..'z'); # ('a', 'b', ..., 'z')
for my $i (1..100) { ... } # Loop 1 to 100
In scalar context, .. and ... are flip-flop operators (stateful boolean range).
| Operator | Operation | Example |
=~ | Match | $str =~ /pattern/ |
!~ | Not match | $str !~ /pattern/ |
Binding operators connect strings with regex operations.
if ($email =~ /\@/) { ... } # Contains @
if ($name !~ /^\d/) { ... } # Doesn't start with digit
| Operator | Operation | Example |
- | Negation | -$x |
+ | Unary plus | +$x |
my $neg = -5;
my $pos = +$x; # Numeric context
| Operator | Operation | Example |
! | Not | !$x |
not | Not (low precedence) | not $x |
if (!$error) { ... }
die "Failed" if not $ok;
| Operator | Operation | Example |
~ | Bitwise complement | ~$x |
my $inverted = ~$bits;
| Operator | Operation | Example |
\ | Create reference | \$x, \@arr, \%hash |
my $scalar_ref = \$value;
my $array_ref = \@data;
my $hash_ref = \%config;
| Operator | Operation | When evaluated |
++$x | Pre-increment | After increment |
--$x | Pre-decrement | After decrement |
$x++ | Post-increment | Before increment |
$x-- | Post-decrement | Before decrement |
my $x = 5;
my $a = ++$x; # $x is 6, $a is 6
my $b = $x++; # $x is 7, $b is 6
String increment: ++ on strings performs “magic increment” (Perl-style).
my $s = "aa";
$s++; # "ab"
$s++; # "ac"
File test operators check properties of files and filehandles. All return true/false except -s which returns file size.
| Operator | Test | Returns |
-e | Exists | Boolean |
-r | Readable | Boolean |
-w | Writable | Boolean |
-x | Executable | Boolean |
-o | Owned by effective UID | Boolean |
-R | Readable by real UID | Boolean |
-W | Writable by real UID | Boolean |
-X | Executable by real UID | Boolean |
-O | Owned by real UID | Boolean |
-z | Zero size | Boolean |
-s | Non-zero size | Size in bytes or false |
-f | Regular file | Boolean |
-d | Directory | Boolean |
-l | Symbolic link | Boolean |
-p | Named pipe (FIFO) | Boolean |
-S | Socket | Boolean |
-b | Block special file | Boolean |
-c | Character special file | Boolean |
-t | TTY (terminal) | Boolean |
-u | Setuid bit set | Boolean |
-g | Setgid bit set | Boolean |
-k | Sticky bit set | Boolean |
-T | Text file | Boolean |
-B | Binary file | Boolean |
-M | Modification time (days) | Number |
-A | Access time (days) | Number |
-C | Inode change time (days) | Number |
if (-e $file) { ... } # File exists
if (-f $path && -r $path) { ... } # Regular file and readable
my $size = -s $file; # Size in bytes
if (-d $path) { ... } # Is directory
Stacked file tests: -f -w -r $file checks all three conditions.
| Operator | Operation | Example |
defined | Check if defined | defined $x |
if (defined $value) { ... }
| Operator | Operation | Example |
= | Assignment | $x = 5 |
my $x = 10;
my ($a, $b, $c) = (1, 2, 3); # List assignment
All binary operators have compound assignment forms:
| Operator | Equivalent | Example |
+= | $x = $x + $y | $x += 5 |
-= | $x = $x - $y | $x -= 3 |
*= | $x = $x * $y | $x *= 2 |
/= | $x = $x / $y | $x /= 10 |
%= | $x = $x % $y | $x %= 7 |
**= | $x = $x ** $y | $x **= 2 |
.= | $x = $x . $y | $str .= "more" |
x= | $x = $x x $y | $str x= 3 |
&= | $x = $x & $y | $bits &= $mask |
| ` | =` | `$x = $x |
^= | $x = $x ^ $y | $x ^= $y |
<<= | $x = $x << $y | $x <<= 2 |
>>= | $x = $x >> $y | $x >>= 1 |
&&= | $x = $x && $y | $x &&= $default |
| ` | | =` |
//= | $x = $x // $y | $x //= 0 |
my $count = 10;
$count += 5; # 15
$count *= 2; # 30
my $path = "/home";
$path .= "/user"; # "/home/user"
$cache ||= load_data(); # Only load if $cache is false
$config //= {}; # Only assign if $config is undef
| Operator | Syntax | Example |
? : | Conditional | $cond ? $then : $else |
my $result = $x > 0 ? "positive" : "non-positive";
my $max = $a > $b ? $a : $b;
Ternary as lvalue: The ternary operator can be used as an assignment target.
($x > 0 ? $pos : $neg) = 10; # Assigns to $pos or $neg
| Syntax | Operation | Example |
$arr[index] | Array element access | $arr[0] |
$hash{key} | Hash element access | $hash{name} |
@arr[indices] | Array slice | @arr[1, 3, 5] |
@hash{keys} | Hash slice | @hash{qw(a b c)} |
my $first = $arr[0];
my $value = $hash{key};
my @subset = @arr[0, 2, 4]; # Elements 0, 2, 4
my @values = @hash{'a', 'b'}; # Values for keys 'a', 'b'
| Syntax | Operation | Example |
->[] | Array deref subscript | $aref->[0] |
->{} | Hash deref subscript | $href->{key} |
->() | Method call | $obj->method() |
my $element = $array_ref->[5];
my $value = $hash_ref->{name};
my $result = $object->method(@args);
| Operator | Operation | Use |
, | List separator | (1, 2, 3) |
=> | Fat comma | key => value |
The fat comma (=>) autoquotes barewords on its left side.
my %hash = (
name => "John", # 'name' autoquoted
age => 30,
);
Highest to lowest precedence (same as Perl 5):
- Terms and list operators (left)
-> (left)
++ -- (none)
** (right)
! ~ \ unary + unary - (right)
=~ !~ (left)
* / % x (left)
+ - . (left)
<< >> (left)
- Named unary operators
< > <= >= lt gt le ge (none)
== != <=> eq ne cmp ~~ (none) — ~~ smart match is partial
& (left)
| ^ (left)
&& (left)
|| // (left)
.. ... (none)
?: (right)
= += -= etc. (right)
, => (left)
- List operators (right)
not (right)
and (left)
or xor (left)
Use parentheses when precedence is unclear.
Operators execute sequentially by default. PetaPerl’s parallelization applies at the loop/map/grep level, not individual operators.
- Bitwise operations compile to native machine instructions
- String concatenation may allocate new memory (use
.= for efficiency)
- Numeric operations are optimized for integers and floats separately