这个脚本:
#!/usr/bin/perl
use strict;
use warnings;
my ${fh};
open($fh, '<', "some_file.txt") or die "fail\n";
while(my $line = <${fh}> ) {
print $line;
}
close $fh;
Run Code Online (Sandbox Code Playgroud)
输出:
GLOB(0x5bcc2a0)
Run Code Online (Sandbox Code Playgroud)
为什么这是输出?
如果我<${fh}>改为<$fh>,它将some_file.txt按预期逐行打印.我认为括号可以用来分隔变量名称,这my ${var}将是相同的my $var.
是否有其他情况下添加{}变量名称会导致问题?
我在Red Hat和Cygwin Perl 5.14上尝试了Perl 5.8.8.
Thi*_*Not 18
从上一节<>中perlop中:
如果尖括号包含的是一个简单的标量变量(例如,
$foo),那么该变量包含要从中输入的文件句柄的名称,或者其typeglob,或者对它的引用.例如:Run Code Online (Sandbox Code Playgroud)$fh = \*STDIN; $line = <$fh>;如果尖括号内的内容既不是文件句柄也不是包含文件句柄名称,typeglob或typeglob引用的简单标量变量,则它被解释为要进行全局化的文件名模式,以及文件名列表或列表中的下一个文件名返回,具体取决于上下文.这种区别仅仅是出于句法原因而确定的.这意味着
<$x>总是readline()来自间接句柄,但<$hash{key}>总是一个glob().那是因为它$x是一个简单的标量变量,但$hash{key}不是 - 它是一个哈希元素.甚至<$x >(注意额外的空间)被视为glob("$x "),而不是readline($x).
你可以用B :: Concise看到这个:
$ perl -MO=Concise -e'<$fh>'
5 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
4 <1> readline[t1] vK*/1 ->5
- <1> ex-rv2sv sK/1 ->4
3 <$> gvsv(*fh) s ->4
-e syntax OK
$ perl -MO=Concise -e'<${fh}>'
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 70 -e:1) v:{ ->3
5 <@> glob[t1] vK/1 ->6
- <0> ex-pushmark s ->3
- <1> ex-rv2sv sK/1 ->4
3 <$> gvsv(*fh) s ->4
4 <$> gv(*_GEN_0) s ->5
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
ike*_*ami 11
<> 手段 readline(ARGV)<IDENTIFIER> 手段 readline(IDENTIFIER)<$IDENTIFIER> 手段 readline($IDENTIFIER)<...> (其他任何东西)意味着 glob(qq<...>)所以,
<$fh> 手段 readline($fh)<${fh}>意思glob(qq<${fh}>)是,与...相同glob("$fh").glob 用于从模式生成许多字符串或文件名.
在这种情况下,文件句柄的字符串化是GLOB(0x5bcc2a0).这被传递给glob,但这些字符都没有特殊含义glob,因此glob只返回该字符串.