From 5074ca1e20bb3d582b0dad444e756606fe0df4a2 Mon Sep 17 00:00:00 2001 From: short <> Date: Sun, 18 Sep 2005 06:43:14 +0000 Subject: [PATCH] +Hash tied to provide additional keys/values than the original. --- Hash/Makefile.am | 3 +- Hash/Merge.pm | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 Hash/Merge.pm diff --git a/Hash/Makefile.am b/Hash/Makefile.am index e1e05a3..10b3bf4 100644 --- a/Hash/Makefile.am +++ b/Hash/Makefile.am @@ -23,5 +23,6 @@ EXTRA_DIST+= \ Sub.pm \ Readonly.pm \ RestrictTo.pm \ - RecordKeys.pm + RecordKeys.pm \ + Merge.pm diff --git a/Hash/Merge.pm b/Hash/Merge.pm new file mode 100644 index 0000000..376cb18 --- /dev/null +++ b/Hash/Merge.pm @@ -0,0 +1,122 @@ +# $Id$ +# Hash tied to provide additional keys/values than the original. +# Copyright (C) 2005 Jan Kratochvil +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; exactly version 2 of June 1991 is required +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +package My::Hash::Merge; +our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; }; +our $CVS_ID=q$Id$; +use strict; +use warnings; +use My::Web; # for &Wrequire +Wrequire 'My::Hash'; +our @ISA=qw(My::Hash); +use Carp qw(cluck confess); + + +sub TIEHASH($@) +{ +my($class,@parents)=@_; + + my $self=bless {},$class; + for my $parent (@parents) { + # Possibly upgrade unref("HASH")es: + $parent=$class->SUPER::TIEHASH($parent)->{"parent"}; + push @{$self->{"parents"}},$parent; + } + return $self; +} + +sub key_find($$) +{ +my($self,$key)=@_; + + my $count=0; + my $first; + for my $parent (@{$self->{"parents"}}) { + next if !exists $parent->{$key}; + $count++; + $first||=$parent; + } + # 0 IS allowed here. + cluck "Duplicity ($count-icity) for key: $key" if $count>=2; + $first||=$self->{"parents"}[0]; + return $first; +} + +sub STORE($$$) +{ +my($this,$key,$value)=@_; + + my $first=$this->key_find($key); + $first->{$key}=$value; +} + +sub FETCH($$) +{ +my($this,$key)=@_; + + my $first=$this->key_find($key); + return if !$first; + return $first->{$key}; +} + +sub FIRSTKEY($) +{ +my($this)=@_; + +confess "TODO: Not yet implemented."; +} + +sub NEXTKEY($$) +{ +my($this,$lastkey)=@_; + +confess "TODO: Not yet implemented."; +} + +sub EXISTS($$) +{ +my($this,$key)=@_; + + my $first=$this->key_find($key); + $first||={}; + return exists $first->{$key}; +} + +sub DELETE($$) +{ +my($this,$key)=@_; + + my $first=$this->key_find($key); + delete $first->{$key}; +} + +sub CLEAR($) +{ +my($this)=@_; + +confess "TODO: Not yet implemented."; +} + +sub SCALAR +{ +my($this)=@_; + +confess "TODO: Not yet implemented."; +} + +1; -- 1.8.3.1