Perl fileno和reference

Perl fileno和reference,perl,Perl,我试图使用fileno为我的线程创建一个文件句柄表,我遇到了一个我不能完全理解的情况。考虑下面的代码: use strict; use Data::Dumper; my %fhh; #this is shared, but that's not important for my issue open my $fh , '>', 'out1.txt' ; $fhh{1} = fileno $fh; open my $fh , '>', 'out2.txt' ; $fhh{2} = fi

我试图使用fileno为我的线程创建一个文件句柄表,我遇到了一个我不能完全理解的情况。考虑下面的代码:

use strict;
use Data::Dumper;
my %fhh; #this is shared, but that's not important for my issue
open my $fh , '>', 'out1.txt' ;
$fhh{1} = fileno $fh;
open my $fh , '>', 'out2.txt' ;
$fhh{2} = fileno $fh;
open my $fh , '>', 'out3.txt' ;
$fhh{3} = fileno $fh;
open my $fh , '>', 'out4.txt' ;
$fhh{4} = fileno $fh;
print Dumper \%fhh;
use strict;
use Data::Dumper;
my %fhh;
foreach my $i (1 .. 4){
    my $file = "out" . $i . ".txt";
    open my $fh , '>',  $file ;
    $fhh{$i} = fileno $fh;
}
print Dumper \%fhh;
我得到的结果是:

$VAR1 = {
          '4' => '9',
          '1' => '6',
          '3' => '8',
          '2' => '7'
        };
到目前为止还不错,不幸的是,我需要生成未知数量的句柄,因此我尝试了以下代码:

use strict;
use Data::Dumper;
my %fhh; #this is shared, but that's not important for my issue
open my $fh , '>', 'out1.txt' ;
$fhh{1} = fileno $fh;
open my $fh , '>', 'out2.txt' ;
$fhh{2} = fileno $fh;
open my $fh , '>', 'out3.txt' ;
$fhh{3} = fileno $fh;
open my $fh , '>', 'out4.txt' ;
$fhh{4} = fileno $fh;
print Dumper \%fhh;
use strict;
use Data::Dumper;
my %fhh;
foreach my $i (1 .. 4){
    my $file = "out" . $i . ".txt";
    open my $fh , '>',  $file ;
    $fhh{$i} = fileno $fh;
}
print Dumper \%fhh;
这里我得到了输出:

$VAR1 = {
          '4' => '10',
          '1' => '10',
          '3' => '10',
          '2' => '10'
        };
所以有点不对劲,也许在这里$fh被削弱和丢失了?因此,我尝试了以下方法:

use strict;
use Data::Dumper;
my %fhh;
my @mfw;
foreach my $i (1 .. 4){
    my $file = "out" . $i . ".txt";
    open my $fh , '>',  $file ;
    push @mfw, $fh; 
    $fhh{$i} = fileno $fh;

}
print Dumper \%fhh;
这里的输出是正确的,就像第一个例子一样,所以它看起来确实是一个弱化的问题,但是为什么在第一个例子中没有发生这种情况呢?我每次都在重新定义$fh,即使我在{}中包围整个街区,它仍然可以正常工作,有人能告诉我发生了什么吗?

我使用的是perl 5.14,如果这很重要的话,

我的$fh的作用域是封闭块。此变量是对文件句柄的唯一引用。当文件句柄被销毁时,文件将被关闭,并且文件描述符编号可用于下一个文件。FD只是一个整数,它没有保持文件打开的魔力


通过在数组中保留对打开的文件句柄的引用,可以延长文件句柄的生存期。因此,每个新文件都会得到一个新的FD编号。

hmm我明白了。我尝试将我的第一个示例分成4个块,问题确实出现了。因此,当我在同一块中重新定义变量时,前面的内容不会减弱?@Nullman在代码中没有弱引用。Perl使用引用计数来管理垃圾收集。如果对象的引用计数降至零,则该对象将被销毁。带有
my
的变量只存在到块的末尾。文件描述符不是Perl可以识别的引用。在上一个示例中,数组不断引用文件句柄,因此它们不会被销毁。因此,当我在第一个示例中重新定义$fh时,以前打开的文件句柄在内存中的某个位置仍然打开,直到块结束,但在循环中,它在每次迭代结束时关闭?这是否意味着循环的每次迭代都是一个单独的块?我发现了一个解释,似乎循环迭代确实是独立的是的,每次执行
my
时,都会得到一个新变量。同名的旧变量仍然存在,但不可见。相反,循环体中的变量在块的末尾被销毁。