Main Content

What order are operations performed in, in a Perl expression?

Archive - Originally posted on "The Horse's Mouth" - 2011-12-07 06:06:58 - Graham Ellis

Mathemetical operators in Perl aren't simply performed left to right - very early on your Learning to Program in Perl course you'll learn that multiplications and divisions happen before additions and subtractions, and you'll learn that brackets (also know as terms or lists) happen even earlier. Commonly this scheme - which is shared with all the other languages we teach - is referred to as BODMAS:

  Brackets
  Order (sometimes BIDMAS - "Indeces")
  Multiplication
  Division
  Addition
  Subtraction

Thus:

  $demo = 2 + 3 * 4 + 5; # see 1. below
  print "Results is $demo\n";
   
  $demo = (2 + 3) * 4 + 5; # see 2. below
  print "Results is $demo\n";
   
  $demo = (2 + 3) * (4 + 5); # see 3. below
  print "Results is $demo\n";


Will results in 19, 25, and 45, because ...

1. 3 * 4 is 12. 2 + 12 is 14. 14 + 5 is 19.
2. 2 + 3 is 5. 5 * 4 is 20. 20 + 5 is 25.
3. 2 + 3 is 5. 4 + 5 is 9. 5 * 9 is 45.

Full source of this example [here].

Remember that addition and subtraction are actually done at the same time, as are multiplication and division, so "BODMAS" is a bit of a cheat. And also remember that multiplication and division are done from left to right, thus

  $bx = 24 / 2 * 3;
gives a result of 36

but
  $bx = 24 / (2 * 3);
gives a result of 4, as does
  $bx = 24 / 2 / 3;

The majority of operations are performed left to right, but some are run right to left instead, for example =. That's how
  $g = $h = 16;
can work - 16 is assigned to $h and the result (which is a copy of the value assigned) is then assigned to $g.

Finally, for some operations the left -> right or right -> left thing doesn't make any difference, as they can't be chained - the result is of a different type. These are "nonassociative" operations.

Here's a full table of the Perl operators, listed from highest precedence (performed first) to lowest precendence, with a note of which direction they're performed in where applicable.

Operator Direction
terms and list operators (leftward) left
-> left
++ -- n/a
** right
! ~ \ and unary + and - right
=~ !~ left
* / % x left
+ - . left
<< >> left
named unary operators n/a
< > <= >= lt gt le ge n/a
== != <=> eq ne cmp ~~ n/a
& left
| ^ left
&& left
|| // left
.. ... n/a
?: right
= += -= *= etc. right
, => left
list operators (rightward) n/a
not right
and left
or xor left


If in doubt ... add some brackets!

If it gets too complicated in a single statement, consider splitting it for maintainability