Very interesting, and clever to make a JAPH out of it!
The first time you evaluate ($a & $b), the two arguments are strings ("12" and "8"), so it is the string version of the "&" operator. The result is 0.
But then you do a numerical comparison with $b. So $b's internal scalar caches $b's integer value along with its string value.
Now the second time you evaluate ($a & $b), $b has an integer value inside, so it is treated as an integer (this must the preference of bitwise operators?). By the table below, you can see that as long as one of the arguments to the "&" operator is considered to be an integer, we use the integer/bitwise version of the operator (and the result is 8 this time).
print "12" & "8", $/; # 0
print 12 & 8, $/; # 8
print 12 & "8", $/; # 8
print "12" & 8, $/; # 8
| [reply] [d/l] |
A bit of both. This is an interaction between bitwise integer ops vs
bitwise string ops and how strings and numbers are autoconverted to each other and how the respective string/integer values are cached separately within a single scalar (cf. Scalar::Util::dualvar).
Makeshifts last the longest.
| [reply] |
print$_=$_&1?"Perl hacker!":"Just another ",$_?"Perl hacker!":"Just an
+other "
| [reply] [d/l] |