为什么$ {fh}在逐行读取时的行为与$ fh不同?

hma*_*tt1 10 perl

这个脚本:

#!/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,或者对它的引用.例如:

$fh = \*STDIN;
$line = <$fh>;
Run Code Online (Sandbox Code Playgroud)

如果尖括号内的内容既不是文件句柄也不是包含文件句柄名称,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只返回该字符串.

  • @Kaz,你从哪里得到的?我的帖子用标记来定义它.即使它确实使用了一种子语言(比如`m //`,`tr ///`,sprintf`和`glob` do),我也不明白为什么会让你的短裤得到结. (4认同)
  • @Kaz,在这个答案中也是如此.所以呢?你为什么提这个? (2认同)