diff -Naur old/lib/Tie/ExtraHash.pm new/lib/Tie/ExtraHash.pm --- old/lib/Tie/ExtraHash.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/Tie/ExtraHash.pm 2018-09-08 19:59:23.713046870 +0200 @@ -0,0 +1,103 @@ +package Tie::ExtraHash; + +use strict; +use warnings; + +our $VERSION = '1.06'; + +=head1 NAME + +Tie::ExtraHash - base class definition for tied hashes + +=head1 SYNOPSIS + + package NewExtraHash; + + use parent 'Tie::ExtraHash'; + + # All methods provided by default, define + # only those needing overrides + # Accessors access the storage in %{$_[0][0]}; + # TIEHASH should return an array reference with the first element + # being the reference to the actual storage + sub DELETE { + $_[0][1]->('del', $_[0][0], $_[1]); # Call the report writer + delete $_[0][0]->{$_[1]}; # $_[0]->SUPER::DELETE($_[1]) + } + + + package main; + + tie %new_extra_hash, 'NewExtraHash', + sub {warn "Doing \U$_[1]\E of $_[2].\n"}; + +=head1 DESCRIPTION + +The B class provide most methods for hashes described in +L (the exceptions are C and C). They cause tied +hashes to behave exactly like standard hashes, and allow for selective +overwriting of methods. + +For developers wishing to write their own tied hashes, the required methods +are briefly defined in L. See the L section for more +detailed descriptive, as well as example code. + +=head1 Inheriting from B + +The accessor methods assume that the actual storage for the data in the tied +hash is in the hash referenced by C<(tied(%tiedhash))-E[0]>. Thus +overwritten C method should return an array reference with the first +element being a hash reference, and the remaining methods should operate on the +hash C<< %{ $_[0]->[0] } >>: + + package ReportHash; + + use strict; + use warnings; + use parent 'Tie::ExtraHash'; + + sub TIEHASH { + my $class = shift; + my $storage = bless [{}, @_], $class; + warn "New ReportHash created, stored in $storage.\n"; + $storage; + } + sub STORE { + warn "Storing data with key $_[1] at $_[0].\n"; + $_[0][0]{$_[1]} = $_[2] + } + + 1; + +The default C method stores "extra" arguments to tie() starting +from offset 1 in the array referenced by C; this is the +same storage algorithm as in TIEHASH subroutine above. Hence, a typical +package inheriting from B does not need to overwrite this +method. + +=head1 C and C + +The methods C and C are not defined in B. +Tied hashes do not require presence of these methods, but if defined, the +methods will be called in proper time, see L. + +If needed, these methods should be defined by the package inheriting from +B. + +=head1 MORE INFORMATION + +See L + +=cut + +sub TIEHASH { my $p = shift; bless [{}, @_], $p } +sub STORE { $_[0][0]{$_[1]} = $_[2] } +sub FETCH { $_[0][0]{$_[1]} } +sub FIRSTKEY { my $a = scalar keys %{$_[0][0]}; each %{$_[0][0]} } +sub NEXTKEY { each %{$_[0][0]} } +sub EXISTS { exists $_[0][0]->{$_[1]} } +sub DELETE { delete $_[0][0]->{$_[1]} } +sub CLEAR { %{$_[0][0]} = () } +sub SCALAR { scalar %{$_[0][0]} } + +1; diff -Naur old/lib/Tie/Hash.pm new/lib/Tie/Hash.pm --- old/lib/Tie/Hash.pm 2018-09-08 19:29:56.710938333 +0200 +++ new/lib/Tie/Hash.pm 2018-09-08 20:15:20.396843988 +0200 @@ -1,65 +1,35 @@ package Tie::Hash; -our $VERSION = '1.05'; +our $VERSION = '1.06'; =head1 NAME -Tie::Hash, Tie::StdHash, Tie::ExtraHash - base class definitions for tied hashes +Tie::Hash - base class definition for tied hashes =head1 SYNOPSIS package NewHash; - require Tie::Hash; - @ISA = qw(Tie::Hash); + use strict; + use warnings; + use parent 'Tie::Hash'; sub DELETE { ... } # Provides needed method sub CLEAR { ... } # Overrides inherited method - - package NewStdHash; - require Tie::Hash; - - @ISA = qw(Tie::StdHash); - - # All methods provided by default, define - # only those needing overrides - # Accessors access the storage in %{$_[0]}; - # TIEHASH should return a reference to the actual storage - sub DELETE { ... } - - package NewExtraHash; - require Tie::Hash; - - @ISA = qw(Tie::ExtraHash); - - # All methods provided by default, define - # only those needing overrides - # Accessors access the storage in %{$_[0][0]}; - # TIEHASH should return an array reference with the first element - # being the reference to the actual storage - sub DELETE { - $_[0][1]->('del', $_[0][0], $_[1]); # Call the report writer - delete $_[0][0]->{$_[1]}; # $_[0]->SUPER::DELETE($_[1]) - } - - package main; tie %new_hash, 'NewHash'; - tie %new_std_hash, 'NewStdHash'; - tie %new_extra_hash, 'NewExtraHash', - sub {warn "Doing \U$_[1]\E of $_[2].\n"}; =head1 DESCRIPTION -This module provides some skeletal methods for hash-tying classes. See +This class provides some skeletal methods for hash-tying classes. See L for a list of the functions required in order to tie a hash to a package. The basic B package provides a C method, as well -as methods C, C and C. The B and -B packages -provide most methods for hashes described in L (the exceptions -are C and C). They cause tied hashes to behave exactly like standard hashes, +as methods C, C and C. The L and +L classes provide most methods for hashes described in +L (the exceptions are C and C). They cause tied +hashes to behave exactly like standard hashes, and allow for selective overwriting of methods. B grandfathers the C method: it is used if C is not defined in the case a class forgets to include a C method. @@ -136,39 +106,10 @@ $_[0]{$_[1]} = $_[2] } - -=head1 Inheriting from B - -The accessor methods assume that the actual storage for the data in the tied -hash is in the hash referenced by C<(tied(%tiedhash))-E[0]>. Thus overwritten -C method should return an array reference with the first -element being a hash reference, and the remaining methods should operate on the -hash C<< %{ $_[0]->[0] } >>: - - package ReportHash; - our @ISA = 'Tie::ExtraHash'; - - sub TIEHASH { - my $class = shift; - my $storage = bless [{}, @_], $class; - warn "New ReportHash created, stored in $storage.\n"; - $storage; - } - sub STORE { - warn "Storing data with key $_[1] at $_[0].\n"; - $_[0][0]{$_[1]} = $_[2] - } - -The default C method stores "extra" arguments to tie() starting -from offset 1 in the array referenced by C; this is the -same storage algorithm as in TIEHASH subroutine above. Hence, a typical -package inheriting from B does not need to overwrite this -method. - =head1 C, C and C -The methods C and C are not defined in B, -B, or B. Tied hashes do not require +The methods C and C are not defined in B. +Tied hashes do not require presence of these methods, but if defined, the methods will be called in proper time, see L. @@ -178,6 +119,54 @@ B, B, or B. See L to find out what happens when C does not exist. +=head1 Legacy + +Old versions of Tie::Hash up to 1.05 included the classes B and +B, requiring the following workarounds to inherit from +B resp. B: + + package NewStdHash; + + use strict; + use warnings; + + use Tie::Hash; + our @ISA = qw( Tie::StdHash ); + + package NewExtraHash; + + use strict; + use warnings; + + use Tie::Hash; + our @ISA = qw( Tie::ExtraHash ); + +To provide compatibility with old code, B automatically loads +B and B. + +New code should load and inherit from B, B and +B via C: + + + package NewHash; + + use strict; + use warnings; + use parent 'Tie::Hash'; + + package NewStdHash; + + use strict; + use warnings; + use parent 'Tie::StdHash'; + + package NewExtraHash; + + use strict; + use warnings; + use parent 'Tie::ExtraHash'; + + =head1 MORE INFORMATION The packages relating to various DBM-related implementations (F, @@ -189,6 +178,8 @@ use Carp; use warnings::register; +use Tie::StdHash; +use Tie::ExtraHash; sub new { my $pkg = shift; @@ -203,7 +194,7 @@ if ($pkg_new and $pkg ne __PACKAGE__) { my $my_new = __PACKAGE__ -> can ('new'); - if ($pkg_new == $my_new) { + if ($pkg_new == $my_new) { # # Prevent recursion # @@ -238,33 +229,4 @@ } } -# The Tie::StdHash package implements standard perl hash behaviour. -# It exists to act as a base class for classes which only wish to -# alter some parts of their behaviour. - -package Tie::StdHash; -# @ISA = qw(Tie::Hash); # would inherit new() only - -sub TIEHASH { bless {}, $_[0] } -sub STORE { $_[0]->{$_[1]} = $_[2] } -sub FETCH { $_[0]->{$_[1]} } -sub FIRSTKEY { my $a = scalar keys %{$_[0]}; each %{$_[0]} } -sub NEXTKEY { each %{$_[0]} } -sub EXISTS { exists $_[0]->{$_[1]} } -sub DELETE { delete $_[0]->{$_[1]} } -sub CLEAR { %{$_[0]} = () } -sub SCALAR { scalar %{$_[0]} } - -package Tie::ExtraHash; - -sub TIEHASH { my $p = shift; bless [{}, @_], $p } -sub STORE { $_[0][0]{$_[1]} = $_[2] } -sub FETCH { $_[0][0]{$_[1]} } -sub FIRSTKEY { my $a = scalar keys %{$_[0][0]}; each %{$_[0][0]} } -sub NEXTKEY { each %{$_[0][0]} } -sub EXISTS { exists $_[0][0]->{$_[1]} } -sub DELETE { delete $_[0][0]->{$_[1]} } -sub CLEAR { %{$_[0][0]} = () } -sub SCALAR { scalar %{$_[0][0]} } - 1; diff -Naur old/lib/Tie/StdHash.pm new/lib/Tie/StdHash.pm --- old/lib/Tie/StdHash.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/Tie/StdHash.pm 2018-09-08 19:57:06.102753649 +0200 @@ -0,0 +1,91 @@ +package Tie::StdHash; + +use strict; +use warnings; + +our $VERSION = '1.06'; + +=head1 NAME + +Tie::StdHash - base class definition for tied hashes + +=head1 SYNOPSIS + + package NewStdHash; + + use strict; + use warnings; + use parent 'Tie::StdHash'; + + # All methods provided by default, define + # only those needing overrides + # Accessors access the storage in %{$_[0]}; + # TIEHASH should return a reference to the actual storage + sub DELETE { ... } + + package main; + + tie %new_std_hash, 'NewStdHash'; + +=head1 DESCRIPTION + +The B class provide most methods for hashes described in +L (the exceptions are C and C). It cause tied hashes +to behave exactly like standard hashes, and allow for selective overwriting of +methods. + +For developers wishing to write their own tied hashes, the required methods +are briefly defined in L. See the L section for more detailed +descriptive, as well as example code. + +=head1 Inheriting from B + +The accessor methods assume that the actual storage for the data in the tied +hash is in the hash referenced by C. Thus overwritten +C method should return a hash reference, and the remaining methods +should operate on the hash referenced by the first argument: + + package ReportHash; + + use strict; + use warnings; + use parent 'Tie::StdHash'; + + sub TIEHASH { + my $storage = bless {}, shift; + warn "New ReportHash created, stored in $storage.\n"; + $storage + } + sub STORE { + warn "Storing data with key $_[1] at $_[0].\n"; + $_[0]{$_[1]} = $_[2] + } + + 1; + +=head1 C and C + +The methods C and C are not defined in B. +Tied hashes do not require presence of these methods, but if defined, the +methods will be called in proper time, see L. + +If needed, these methods should be defined by the package inheriting from +B. + +=head1 MORE INFORMATION + +See L + +=cut + +sub TIEHASH { bless {}, $_[0] } +sub STORE { $_[0]->{$_[1]} = $_[2] } +sub FETCH { $_[0]->{$_[1]} } +sub FIRSTKEY { my $a = scalar keys %{$_[0]}; each %{$_[0]} } +sub NEXTKEY { each %{$_[0]} } +sub EXISTS { exists $_[0]->{$_[1]} } +sub DELETE { delete $_[0]->{$_[1]} } +sub CLEAR { %{$_[0]} = () } +sub SCALAR { scalar %{$_[0]} } + +1;