为什么SEEK_SET会失败?

时间:2012-09-05 13:39:07

标签: perl yaml

当我运行以下脚本时,我得到了

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;
}

1 个答案:

答案 0 :(得分:2)

您拨打write_yaml_with_lock()两次。第一次调用它时$acc_fh仍为undef,因为直到read_yaml_with_lock()向下两行才会设置它。