0

When I run the below script I get

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

where line 52 is

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

The purpose of the script is to reproduce why I get corrupt yaml files, so the global file handles are suppose to be there.

My theory is that newly written yaml files are not overwritten, and therefore if the newly written yaml is smaller than the old, then old data will still be in the new yaml file.

Question

Can anyone see what is wrong with my script?

#!/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;
}
4

1 回答 1

2

You call write_yaml_with_lock() twice. The first time you call it $acc_fh is still undef because it is not set until two lines further down via read_yaml_with_lock().

于 2012-09-05T13:43:29.617 回答