我最近在Perl中发现了一个似乎是未记录的变量%_.我不记得我是如何偶然发现它的(它是上周),但我的代码中有一个拼写错误,map而不是$_->{key}我使用过的$_{key}.当我发现错误时,我很惊讶它没有产生错误,我验证了它use strict并且use warnings已经到位.
所以,我做了一个小测试,确定它运行时没有任何警告或错误:
$ perl
use strict;
use warnings;
print keys %_;
$
Run Code Online (Sandbox Code Playgroud)
所以,我能想到的%_只是在某处定义的.我找不到它perlvar,所以这是什么交易?它在上面的脚本中没有任何内容.
ike*_*ami 22
标点变量免于严格.这就是为什么你不必使用our $_;之前使用的东西$_.来自perlvar,
以数字,控制字符或标点符号开头的Perl标识符也可免于
strict 'vars'错误.
%_没有证件.来自perlvar,
Perl变量名也可以是数字序列或单个标点符号或控制字符(不推荐使用文字控制字符形式).这些名称都保留给Perl的特殊用途
您可以使用名为hash的哈希,_因为它_是变量的有效名称.(我相信你很熟悉$_和@_.)
没有Perl内置当前设置它或%_隐式读取,但标点符号变量如%_保留.
请注意,标点符号变量也很特殊,因为它们是"超级全局变量".这意味着不合格%_是指%_在根包中,而不是%_在当前包中.
$ perl -E'
%::x = ( "%::x" => 1 );
%::_ = ( "%::_" => 1 );
%Foo::x = ( "%Foo::x" => 1 );
%Foo::_ = ( "%Foo::_" => 1 );
package Foo;
say "%x = ", keys(%x);
say "%_ = ", keys(%_);
say "%::x = ", keys(%::x);
say "%::_ = ", keys(%::_);
say "%Foo::x = ", keys(%Foo::x);
say "%Foo::_ = ", keys(%Foo::_);
'
%x = %Foo::x
%_ = %::_ <-- surprise!
%::x = %::x
%::_ = %::_
%Foo::x = %Foo::x
%Foo::_ = %Foo::_
Run Code Online (Sandbox Code Playgroud)
这意味着忘记使用local %_(如你所做)可能会产生非常深远的影响.
Bor*_*din 15
它没有记录,它只是未使用.你会发现它总是空的
Perl变量名也可以是数字序列或单个标点符号或控制字符......这些名称都保留给Perl的特殊用途; 例如,所有数字名称用于保存正则表达式匹配后由反向引用捕获的数据.
所以%_被保留但未被使用.
哈希变量是最常见的,所以你会发现,你可以用%1,%(等,以及(类似的代码$({xx} = 99是好的),但你会得到不因向后兼容性问题的警告
有效的通用变量名必须以字母开头(utf8编译指示可以是具有Unicode 字母属性的任何字符)或ASCII下划线,当必须后跟至少一个其他字符时
$_是一个全局变量.全局变量存在于符号表中,内置标点符号变量全部存在于包的符号表中main.
你可以看到符号表的内容,main如下所示:
$ perl -MData::Dumper -e'print Dumper \%main::' # or \%:: for short
$VAR1 = {
'/' => *{'::/'},
',' => *{'::,'},
'"' => *{'::"'},
'_' => *::_,
# and so on
};
Run Code Online (Sandbox Code Playgroud)
所有上述条目都是typeglobs,由*sigil 表示.一个类型团,如同与对所有的不同的Perl类型的时隙的容器(例如SCALAR,ARRAY,HASH,CODE).
typeglob允许您使用具有相同标识符的不同变量(sigil之后的名称):
${ *main::foo{SCALAR} } # long way of writing $main::foo
@{ *main::foo{ARRAY} } # long way of writing @main::foo
%{ *main::foo{HASH} } # long way of writing %main::foo
Run Code Online (Sandbox Code Playgroud)
的值$_,@_和%_都存储在main与主要符号表项_.当您访问时%_,您实际上正在访问typeglob中的HASH插槽*main::_(*::_简称).
strict 'vars' 如果您尝试访问没有完全限定名称的全局变量,通常会抱怨,但标点符号变量是免除的:
use strict;
*main::foo = \'bar'; # assign 'bar' to SCALAR slot
print $main::foo; # prints 'bar'
print $foo; # error: Variable "$foo" is not imported
# Global symbol "$foo" requires explicit package name
print %_; # no error
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1123 次 |
| 最近记录: |