Thread Problem mit FileHandle
(24 answers)
Opened by rosti at 2011-04-05 22:27
Wofür brauchst du ein Modul, das mit zählt wie häufig das Modul bezügliche eines Schlüssel zusammen ge"tie"d wurde?
Wenn es dir um das Zählen geht, würde da nicht eine einfache Funktion ausreichen? Etwa so was: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package NumberCount; use strict; use warnings; use Carp; use Storable; use base 'Exporter'; our @EXPORT=qw(count_up count_last); # VARs intern my %vars = (); sub count_up { my $ref=&__get_count_ref; $$ref++; return $$ref } sub count_last { my $ref=&__get_count_ref; return $$ref; } ######################################################################## sub END { for my $file (keys(%vars)) { store($vars{$file}, $file); } } sub __get_count_ref { my $file=shift //croak "No file"; my $key=shift // croak "No key!"; $file=File::Spec->rel2abs($file); unless(exists($vars{$file})) { if(-f $file) { $vars{$file}=retrieve($file) // {}; } else { $vars{$file}={}; } } return \$vars{$file}->{$key}; } 1; Außerdem würde ich Storable zum Serialisieren nutzen, das ist schneller als while zusammen mit pack/unpack Oder willst du zahlen zu einem Schlüssel persistent halten? Ich hatte mal ein Modul geschrieben das so was macht: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 package Tie::Scalar::StorageKeyList; use strict; use warnings; use Carp; use File::Spec; use Storable; use base 'Tie::Scalar'; my %objects; ######################################################################## sub TIESCALAR { my $class=shift; pop(@_) if(@_%2); my %conf=@_; my $file =$conf{file} // croak qq(No file, use "file" in options!); my $key =$conf{key} // croak qq(No key, use "key" in options!); my $value=$conf{value}; my $pos=defined($conf{position})?int(abs($conf{position})):undef; $file=File::Spec->rel2abs($file); $objects{$file}{keys}=__load($file) unless(exists($objects{$file})); $objects{$file}{counter}++; if(defined($pos)) { if($pos >= $objects{$file}{keycount}{$key}) { $objects{$file}{keycount}{$key}=$pos+1; } } else { $objects{$file}{keycount}{$key}++; $pos=$objects{$file}{keycount}{$key}-1; } my $ref=\$objects{$file}{keys}{$key}[$pos]; $$ref=$value unless(defined($$ref)); my $self={file=>$file, key=>$key, val=>$ref }; return bless($self,$class); } sub FETCH { my $self=shift; return ${$self->{val}}; } sub STORE { my $self=shift; my $val=shift; ${$self->{val}}=$val; } sub DESTROY { my $self=shift; my $file=$self->{file}; $objects{$file}{counter}--; __save($file,$objects{$file}{keys}) if($objects{$file}{counter}==0); } sub delete { my $self=shift; my $p; my $arr=$objects{$self->{file}}{keys}{$self->{key}}; for(0..$#$arr) { my $ref=\$arr->[$_]; if($ref eq $self->{var}) { $p=$_; last; } } if(defined($p)) { $objects{$self->{file}}{keycount}{$self->{key}}--; return splice(@$arr,$p,1); } return undef; } ######################################################################## ######################################################################## sub __load { my $file=shift; return retrieve($file) if(-f $file); return {}; } sub __save { my $file=shift; my $data=shift; return 0 unless $data; store($data, $file); } 1; Ich brauchte zu einem Schlüssel eine Reihe von Werten, die ich persistent gespeichert wissen wollte. EDIT: Mir fällt gerade auf, dass $fh als Paketvariable definiert ist. Es kann passieren, dass $fh auf die falsche Datei zeigt, und dass jede andere nicht geöffnete aber benutzte Datei nicht gespeichert wird. Weiterhin ließt du immer den gesamten Inhalt aus der Datei und überschreibst damit bei jedem tie alle geänderten Werte. Das ist wohl genau dein Problem. Damit kann der Wert eines Schlüssels, bei existierenden Dateien und gespeicherten Schlüsseln, nur um 1 über den gespeicherten Wert steigen. Wenn du eine Prüfung einfügst, in der du testest ob die Datei schon geladen wurde, sollte es Funktionieren. Last edited: 2011-04-06 02:27:02 +0200 (CEST) |