私のスレッドのためのファイルハンドルのテーブルを作るためにfilenoを使用しようとしていますが、私は理解できない状況に遭遇しました。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;
私が手出力は次のとおりです:
$VAR1 = {
'4' => '9',
'1' => '6',
'3' => '8',
'2' => '7'
};
これまでのところは良い、残念ながら私はハンドルの未知の番号を生成する必要があるので、私は次のコードを試してみました:
次のコードを検討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;
出力は、第1の例のように、再び正しいですので、それは確かに弱体化の問題であるようだが、なぜ最初の例ではこの出来事ではないでしょうか?私は毎回$ fhを再定義していますが、{}でブロック全体を囲んでも、それでも問題なく動作します。
重要なことはperl 5.14です。
わかりました。最初の例を4ブロックに分割してみましたが、問題は実際に発生します。ですから、同じブロック内で変数を再定義すると、以前のコンテンツは弱くならないでしょうか? – Nullman
@ Nullmanコードには弱い参照はありません。 Perlはガベージコレクションを管理するために参照カウントを使用します。オブジェクトの参照カウントがゼロになると、オブジェクトは破棄されます。 'my'を持つ変数は、ブロックの終わりまでしか存在しません。ファイル記述子は、Perlが認識する参照ではありません。あなたの最後の例では、配列は破壊されないようにファイルハンドルを参照し続けます。 – amon
最初の例で$ fhを再定義すると、以前に開いたファイルハンドルは、ブロックが終了するまでメモリのどこかでまだ開いていますが、ループでは各繰り返しの最後に閉じます。それはループの各反復が別々のブロックであることを意味しますか? – Nullman