이것은 그것을 하지 않는 방법에 대한 제안입니다 . 상당히 큰 Perl 응용 프로그램에서 버그를 찾는 데 어려움을 겪었습니다. 대부분의 모듈에는 자체 구성 파일이 있습니다. 구성 파일을 전체적으로 읽기 위해 인터넷 어딘가에서이 한 줄의 Perl을 찾았습니다.
# Bad! Don't do that!
my $content = do{local(@ARGV,$/)=$filename;<>};
앞에서 설명한대로 줄 구분 기호를 다시 할당합니다. 그러나 또한 STDIN을 재 할당합니다.
이것은 내가 찾는 데 몇 시간이 걸리는 부작용이 적어도 하나 있었다 : 암시 적 파일 핸들을 제대로 닫지 않는다 (아무것도 호출하지 않기 때문에 close
).
예를 들면 다음과 같습니다.
use strict;
use warnings;
my $filename = 'some-file.txt';
my $content = do{local(@ARGV,$/)=$filename;<>};
my $content2 = do{local(@ARGV,$/)=$filename;<>};
my $content3 = do{local(@ARGV,$/)=$filename;<>};
print "After reading a file 3 times redirecting to STDIN: $.\n";
open (FILE, "<", $filename) or die $!;
print "After opening a file using dedicated file handle: $.\n";
while (<FILE>) {
print "read line: $.\n";
}
print "before close: $.\n";
close FILE;
print "after close: $.\n";
결과 :
After reading a file 3 times redirecting to STDIN: 3
After opening a file using dedicated file handle: 3
read line: 1
read line: 2
(...)
read line: 46
before close: 46
after close: 0
이상한 점은 $.
모든 파일에 대해 라인 카운터 가 하나씩 증가 한다는 것입니다 . 재설정되지 않으며 행 수를 포함하지 않습니다. 그리고 적어도 한 줄을 읽을 때까지 다른 파일을 열 때 0으로 재설정되지 않습니다. 제 경우에는 다음과 같이했습니다.
while($. < $skipLines) {<FILE>};
이 문제로 인해 회선 카운터가 제대로 재설정되지 않았기 때문에 조건이 거짓이었습니다. 이것이 버그인지 아니면 단순히 잘못된 코드인지 모르겠습니다 . close;
oder를 호출 close STDIN;
해도 도움이되지 않습니다.
이 읽을 수없는 코드를 열기, 문자열 연결 및 닫기를 사용하여 대체했습니다. 그러나 Brad Gilbert가 게시 한 솔루션은 대신 명시 적 파일 핸들을 사용하기 때문에 작동합니다.
처음에있는 세 줄은 다음으로 바꿀 수 있습니다.
my $content = do{local $/; open(my $f1, '<', $filename) or die $!; my $tmp1 = <$f1>; close $f1 or die $!; $tmp1};
my $content2 = do{local $/; open(my $f2, '<', $filename) or die $!; my $tmp2 = <$f2>; close $f2 or die $!; $tmp2};
my $content3 = do{local $/; open(my $f3, '<', $filename) or die $!; my $tmp3 = <$f3>; close $f3 or die $!; $tmp3};
파일 핸들을 제대로 닫습니다.