2012-09-05 189 views
0

當我運行下面的腳本,我得到爲什麼SEEK_SET失敗?

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

其中線52是

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

腳本的目的是爲了重現爲什麼我收到損壞的YAML文件,所以全球的文件句柄是假設到那裏。

我的理論是,新編寫的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'去除文件是愚蠢的。只要使用'取消鏈接'test.yaml''。但是,不需要這樣做,因爲您使用'>'文件打開模式,無論如何都會截斷您的文件。 – TLP

回答

2

您撥打write_yaml_with_lock()兩次。您第一次給它打電話$acc_fh仍然是undef,因爲它沒有設置,直到通過read_yaml_with_lock()進一步下降兩行。