I'm wondering why/how print
in Perl can have a side-effect.
use Scalar::Util qw/looks_like_number/;
my @A = (5, '2', 'aaa', 1, 'aab');
my @a = map { looks_like_number($_) } @A;
print "1) @a\n";
# prints "4352 1 0 4352 0"
print "A print with a side-effect: @A\n";
@a = map { looks_like_number($_) } @A;
print "2) @a\n";
# prints "1 1 0 1 0"
In this example, looks_like_number
returns 4352 1 0 4352 0
before the print, and 1 1 0 1 0
after the print.
What does print
do to these values to affect how they're interpreted by looks_like_number
?
When interpolating or otherwise concatenating a numeric value, a stringified version needs to be created. This string is stored within the scalar (in addition to the numeric value) for later use, and this can affect which value looks_like_number
returns.
To inspect variables' internals, use Devel::Peek[1].
use Devel::Peek qw( Dump );
my @A = (5, '2', 'aaa');
Dump($_) for @A; # Or: Dump(\@A);
print "@A\n";
Dump($_) for @A;
With Perl 5.20, you get the following: (Rerranged for readability)
Before After
=============================== ===============================
SV = IV(0x4532a78) at 0x4532a88 SV = PVIV(0x45563a0) at 0x4532a88
REFCNT = 2 REFCNT = 2
FLAGS = (IOK,pIOK) FLAGS = (IOK,POK,pIOK,pPOK)
IV = 5 IV = 5
PV = 0x454a870 "5"\0
CUR = 1
LEN = 10
SV = PV(0x45336a0) at 0x4532c08 SV = PV(0x45336a0) at 0x4532c08
REFCNT = 2 REFCNT = 2
FLAGS = (POK,IsCOW,pPOK) FLAGS = (POK,IsCOW,pPOK)
PV = 0x455cf00 "2"\0 PV = 0x455cf00 "2"\0
CUR = 1 CUR = 1
LEN = 10 LEN = 10
COW_REFCNT = 1 COW_REFCNT = 1
SV = PV(0x4533720) at 0x4550b90 SV = PV(0x4533720) at 0x4550b90
REFCNT = 2 REFCNT = 2
FLAGS = (POK,IsCOW,pPOK) FLAGS = (POK,IsCOW,pPOK)
PV = 0x455f210 "aaa"\0 PV = 0x455f210 "aaa"\0
CUR = 3 CUR = 3
LEN = 10 LEN = 10
COW_REFCNT = 1 COW_REFCNT = 1
Look at the FLAGS
. When provided a number, the stringification of the number is cached (stored in the scalar) for future use. This is the side-effect mentioned.
The value returned by looks_like_number
is sometimes a subset of the bits of FLAGS
[2]. This is why the specific value returned varies. It will still return true if it returned true before, and it will still return false if it returned false before.
illguts provides information on the format of scalars.
See Behavior of Scalar::Util's looks_like_number
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With