Perl 是围绕“按照我的意思去做”的核心概念构建的。
标量是一种多用途变量类型,旨在将值隐式转换为适合您正在执行的操作的数据类型。
这样做的原因是因为 perl 是上下文敏感的——它知道不同预期返回值之间的差异。
在基本级别上,您可以使用wantarray 函数看到这一点。 (如下所述 - 可能命名不当,因为我们谈论的是 LIST 上下文)
sub context_test {
if ( not defined wantarray() ) {
print "Void context\n";
}
if ( wantarray() ) {
return ( "List", "Context" );
}
else {
return "scalar context";
}
}
context_test();
my $scalar = context_test();
my @list = context_test();
print "Scalar context gave me $scalar\n";
print "List context gave me @list\n";
这个原则贯穿 perl。如果你愿意,你可以使用Contextual::Return 之类的东西来进一步扩展它——测试标量上下文的数字、字符串和布尔子集之间的差异。
我之所以提到这一点是因为标量是一种特殊的数据类型 - 如果您查看 Scalar::Util,您将看到创建 dualvar 的能力 - 一个在不同上下文中具有不同值的标量。
my $dualvar = Scalar::Util::dualvar ( 666, "the beast" );
print "Numeric:",$dualvar + 0,"\n";
print "String:",$dualvar . '',"\n";
现在,搞乱双变量是创建一些非常烦人且难以追踪的错误的好方法,但重点是 - scalar 是一种神奇的数据类型,perl 总是知道你在做什么结果。
如果您执行字符串操作,perl 会将其视为字符串。如果您执行数字操作,perl 会尝试将其视为数字。
my $value = '4'; #string;
my $newvalue = $value . 3; #because we concat, perl treats _both_ as strings.
print $newvalue,"\n";
my $sum = $newvalue + 7; #perl turns strings back to numbers, because we're adding;
print $sum,"\n";
if ( Scalar::Util::isdual ( $newvalue ) ) { print "newvalue Is a dual var\n" };
if ( not Scalar::Util::isdual ( $sum ) ) { print "sum is NOT a dual var\n"; };
大多数情况下,“上下文”是在 perl 中发生在幕后的事情,您不必担心它。如果您有编程背景,那么在int 和string 之间进行隐式转换的想法可能看起来有点脏。但它大多工作正常。
您可能偶尔会遇到以下错误:
Argument "4a3" isn't numeric in addition (+)
这种方法的一个缺点是这些是运行时错误,因为您没有在“编译”时进行强类型检查。
所以就具体问题而言:
您将收到List Context。
- 如果您随意使用上下文相关的返回类型,您可能会创建一些非常烦人的错误,这些错误会极大地刺激回溯和故障排除。