2012-09-05 6 views
0

나는 아래의 스크립트를 실행하면 I 라인 (52)SEEK_SET이 실패하는 이유는 무엇입니까?

seek $fh, 0, SEEK_SET; # seek back to the beginning of file 

스크립트의 목적은 I가 손상 YAML 파일을 가져 이유를 재현하는 것입니다, 그래서 전역 파일 핸들을 가정 해있다

Can't use an undefined value as a symbol reference at ./yaml-test.pl line 52. 

여기서 얻을 거기에있다.

필자의 이론은 새로 작성된 yaml 파일을 덮어 쓰지 않기 때문에 새로 작성된 yaml이 이전 파일보다 작 으면 이전 데이터가 새 yaml 파일에 남아있게된다는 것입니다.

질문

사람이 내 스크립트에 어떤 문제가 있는지 볼 수 있을까요?

#!/usr/bin/perl 

use strict; 
use YAML::Syck; 
use Fcntl ':flock', 'SEEK_SET'; 
use warnings; 
use Data::Dumper; 

my $acc; 
my $acc_fh; 

$acc->{1}{name1} = "abc"; 


system("rm -f test.yaml"); 

# write initial 
open F, '>', 'test.yaml'; 
print F YAML::Syck::Dump($acc); 
close F; 


$acc->{1}{name2} = "abc"; 

write_yaml_with_lock($acc, $acc_fh); 

$acc->{1}{name3} = "abc"; 

($acc, $acc_fh) = read_yaml_with_lock('test.yaml'); 

$acc->{1}{name4} = "abc"; 

write_yaml_with_lock($acc, $acc_fh); 



sub read_yaml_with_lock { 
    my ($file) = @_; 

    open my $fh, '+<', $file or die $!; 
    flock($fh, LOCK_EX) or die $!; 

    my $obj = YAML::Syck::LoadFile($fh); # this dies on failure 
    return ($obj, $fh); 
} 

sub write_yaml_with_lock { 
    my ($obj, $fh) = @_; 

    my $yaml = YAML::Syck::Dump($obj); 
    $YAML::Syck::ImplicitUnicode = 1; 
    seek $fh, 0, SEEK_SET; # seek back to the beginning of file 

    print $fh $yaml . "---\n"; 
    close $fh; 
} 
+3

'system'을 사용하여 파일을 제거하는 것은 어리석은 일입니다. 그냥'unlink 'test.yaml'을 사용하십시오. 그러나 어쨌든 파일을 자르는'>'파일 열기 모드를 사용하기 때문에 그렇게 할 필요는 없습니다. – TLP

답변

2

write_yaml_with_lock()으로 두 번 전화하십시오. 처음으로 $acc_fh이라고하면 read_yaml_with_lock()을 통해 두 줄 더 내려갈 때까지 설정되지 않기 때문에 여전히 undef입니다.

관련 문제