我想知道为什么/如何print在Perl中产生副作用.
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"
Run Code Online (Sandbox Code Playgroud)
在此示例中,在打印之前和打印之后looks_like_number返回.4352 1 0 4352 01 1 0 1 0
这是什么print做的这些值来影响他们如何解释looks_like_number?
在插入或以其他方式连接数值时,需要创建字符串化版本.此字符串存储在标量中(除了数值)以供以后使用,这可能会影响looks_like_number返回的值.
要检查变量的内部,请使用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;
Run Code Online (Sandbox Code Playgroud)
使用Perl 5.20,您将获得以下内容:(为了便于阅读而重新排列)
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
Run Code Online (Sandbox Code Playgroud)
看看FLAGS.当提供数字时,数字的字符串化被缓存(存储在标量中)以供将来使用.这是提到的副作用.
返回的值looks_like_number有时是FLAGS[2]的位的子集.这就是返回的具体值变化的原因.如果之前返回true,它仍将返回true,如果之前返回false,它仍将返回false.
illguts提供有关标量格式的信息.