看起来字符串上下文(虽然是真实的东西,并且在“编程Perl”章节“2.7.1。标量和列表上下文”中作为标量上下文的子概念提到),但在我所在的任何地方都没有明确记录能够找到Perldoc。
显然,Perl中的一些内容(例如eq
运算符,或qq //引用插值)会将值强制转换为字符串上下文。
Perl什么时候强加字符串上下文?
perldoc似乎是to contain no useful answer。
答案 0 :(得分:8)
当Perl需要字符串时,Perl将生成包含标量的结构的PV(字符串组件)。了解这一点的最佳位置是perlguts,perldata,以及较小程度的perlop。但基本上任何时候用标量执行字符串类型操作,它都会强加你对字符串上下文的感觉,如果标量只包含一个整数,那么将从该值隐式创建一个字符串。
所以,如果你有$var = 15
,它在$var
中放置一个整数,然后说if( $var eq '15' ) {...}
,那么将生成整数15的字符串表示并存储在PV中标量结构的一部分。
这绝不是一个完整的清单,但以下内容将起到作用:
字符串比较运算符(eq
,ne
,ge
,le
,lt
,gt
)
匹配左操作数的绑定运算符(=~
,!~
)
字符串插值(qq{$var}
,"$var"
,qx/$var/
和反引号)
正则表达式运算符(m/$interpolated/
,s/$interpolated//
,qr/$interpolated/
)
<<"HERE"
(此处有插值文档)
哈希键$hash{$stringified_key}
。
.
连接运算符。
在较新版本的Perl中,启用了bitwise
功能后,字符串按位运算符&.
,|.
,^.
和~.
,以及它们的赋值对应项(如&.=
)将在其操作数上调用字符串上下文。
vec
在其第一个参数上强制使用字符串上下文。
可能还有其他人。但好消息是,这个实现细节很少泄漏到“胆量”级别之外的抽象层。可以关注的一个例子是编码JSON,因为我熟悉的JSON模块都会查看给定标量是否有PV组件来决定是将值编码为字符串还是数字。 / p>
正如Joel在下面的评论中所指出的那样,自Perl 5.6.0版本以来一直在Perl核心中的Devel::Peek
模块可以方便地反省标量的内容:
use Devel::Peek;
my $foo = 12;
print "Initial state of \$foo:\n";
Dump($foo);
my $bar = "$foo";
print "\n\nFinal state of \$foo:\n";
Dump($foo);
该代码产生的输出是:
Initial state of $foo:
SV = IV(0x56547b4bb2a0) at 0x56547b4bb2b0
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 12
Final state of $foo:
SV = PVIV(0x56547b4b5880) at 0x56547b4bb2b0
REFCNT = 1
FLAGS = (IOK,POK,pIOK,pPOK)
IV = 12
PV = 0x56547b4ab600 "12"\0
CUR = 2
LEN = 10
如您所见,在强制字符串化后,有一个PV
元素,POK
标记已设置,并且CUR
和LEN
字段存在以指示字符串缓冲区的长度和内容的当前长度。