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;