[This feature is no longer experimental, starting in v5.28. Declaring use 5.28
automatically enables them.]
Most Perl operators force their context on the values. For example, the numeric addition operator, +
, forces its values to be numbers. To “add” strings, you use a separate operator, the string concatenation operator, .
(which looks odd at the end of a sentence).
The bitwise operators, however, look at the value to determine their context. With a lefthand value that has a numeric component, the bitwise operators do numeric things. With a lefthand value that’s a string, the bit operators become string operators. That’s certainly one of Perl’s warts, which I’ll fix at the end of this article with a new feature from v5.22.
Consider this demonstration where the operator is the same but the type of argument changes:
my $number = 0x80 ^ 0x20; my $mixed = "P" ^ 0x20; my $string = "P" ^ " "; print <<"HERE"; Number is $number Mixed is $mixed String is $string HERE
The result is different in each case:
Number is 160 Mixed is 32 String is p
This leads to the joke about the difference between Perl and perl being one bit:
% perl -e 'printf "[%b]\n", ord("perl" ^ "Perl")' [100000]
This is a problem if you want a particular context. You have to force either the string or numeric context. If either of the operands has a numeric component (see Create your own dualvars) it’s a numeric operation:
"$var" ^ "$var2" $var + 0 ^ $var2
Or, you can skip all this messiness with a new experimental feature from v5.22. The bitwise
feature makes the bitwise operators always work in numeric context. You have to import this one explicitly because it’s not automatically imported as part of the default new feature set:
use v5.22; use feature qw(bitwise); no warnings qw(experimental::bitwise); my $number = 0x80 ^ 0x20; my $mixed = "P" ^ 0x20; my $string = "P" ^ " "; print <<"HERE"; Number is $number Mixed is $mixed String is $string HERE
Now the output for the last case is 0
instead of p
:
Number is 160 Mixed is 32 String is 0
This is probably what you want most of the time. And, if you don't want this, do you really want a bitwise operator?