New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PATCH] Perl can't inherit from Tie::StdHash, Tie::StdArray, Tie::StdScalar without loading Tie::Hash, Tie::Array, Tie::Scalar #16706
Comments
From alexander@foken.deThis is a bug report for perl from alexander@foken.de, Can't inherit from Tie::StdHash, Tie::StdArray, Tie::StdScalar via use use parent 'Tie::StdHandle' works fine because Tie::StdHandle is My patch moves the Tie::Std* classes to their own files and removes a Test case and patch attached. Longer description starts at <https://perlmonks.org/?node_id=1221954> First fully working patch against 5.20.0 at Flags: Site configuration information for perl 5.28.0: Configured by alex at Sun Sep 16 20:04:13 CEST 2018. Summary of my perl5 (revision 5 version 28 subversion 0) configuration: @INC for perl 5.28.0: Environment for perl 5.28.0: PATH=/home/alex:/command:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib64/qt/bin:/usr/share/texmf/bin |
From alexander@foken.depatch.diffdiff -pNaur perl-5.28.0.orig/MANIFEST perl-5.28.0/MANIFEST
--- perl-5.28.0.orig/MANIFEST 2018-05-23 15:29:56.000000000 +0200
+++ perl-5.28.0/MANIFEST 2018-09-16 18:29:15.492576340 +0200
@@ -4747,7 +4747,8 @@ lib/Tie/Array/push.t Test for Tie::Arra
lib/Tie/Array/splice.t Test for Tie::Array::SPLICE
lib/Tie/Array/std.t Test for Tie::StdArray
lib/Tie/Array/stdpush.t Test for Tie::StdArray
-lib/Tie/ExtraHash.t Test for Tie::ExtraHash (in Tie/Hash.pm)
+lib/Tie/ExtraHash.pm Tie::ExtraHash
+lib/Tie/ExtraHash.t Test for Tie::ExtraHash
lib/Tie/Handle.pm Base class for tied handles
lib/Tie/Handle/stdhandle.t Test for Tie::StdHandle
lib/Tie/Handle/stdhandle_from_handle.t Test for Tie::StdHandle/Handle backwards compat
@@ -4755,7 +4756,10 @@ lib/Tie/Hash.pm Base class for tied ha
lib/Tie/Hash.t See if Tie::Hash works
lib/Tie/Scalar.pm Base class for tied scalars
lib/Tie/Scalar.t See if Tie::Scalar works
+lib/Tie/StdArray.pm Tie::StdArray
lib/Tie/StdHandle.pm Tie::StdHandle
+lib/Tie/StdHash.pm Tie::StdHash
+lib/Tie/StdScalar.pm Tie::StdScalar
lib/Tie/SubstrHash.pm Compact hash for known key, value and table size
lib/Tie/SubstrHash.t Test for Tie::SubstrHash
lib/Time/gmtime.pm By-name interface to Perl's builtin gmtime
diff -pNaur perl-5.28.0.orig/Porting/Maintainers.pl perl-5.28.0/Porting/Maintainers.pl
--- perl-5.28.0.orig/Porting/Maintainers.pl 2018-06-19 23:15:34.000000000 +0200
+++ perl-5.28.0/Porting/Maintainers.pl 2018-09-16 19:08:13.327438271 +0200
@@ -1406,12 +1406,15 @@ use File::Glob qw(:case);
lib/Thread.{pm,t}
lib/Tie/Array.pm
lib/Tie/Array/
- lib/Tie/ExtraHash.t
+ lib/Tie/ExtraHash.{pm,t}
lib/Tie/Handle.pm
lib/Tie/Handle/
lib/Tie/Hash.{pm,t}
lib/Tie/Scalar.{pm,t}
+ lib/Tie/StdArray.pm
lib/Tie/StdHandle.pm
+ lib/Tie/StdHash.pm
+ lib/Tie/StdScalar.pm
lib/Tie/SubstrHash.{pm,t}
lib/Time/gmtime.{pm,t}
lib/Time/localtime.{pm,t}
diff -pNaur perl-5.28.0.orig/lib/Tie/Array.pm perl-5.28.0/lib/Tie/Array.pm
--- perl-5.28.0.orig/lib/Tie/Array.pm 2018-05-21 14:29:23.000000000 +0200
+++ perl-5.28.0/lib/Tie/Array.pm 2018-09-16 19:08:59.525376168 +0200
@@ -2,12 +2,13 @@ package Tie::Array;
use 5.006_001;
use strict;
-use Carp;
-our $VERSION = '1.07';
+use warnings;
+use Tie::StdArray (); # for backwards compatibility
+
+our $VERSION = '1.08';
# Pod documentation after __END__ below.
-sub DESTROY { }
sub EXTEND { }
sub UNSHIFT { scalar shift->SPLICE(0,0,@_) }
sub SHIFT { shift->SPLICE(0,1) }
@@ -72,42 +73,6 @@ sub SPLICE {
return wantarray ? @result : pop @result;
}
-sub EXISTS {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define an EXISTS method";
-}
-
-sub DELETE {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define a DELETE method";
-}
-
-package Tie::StdArray;
-our @ISA = 'Tie::Array';
-
-sub TIEARRAY { bless [], $_[0] }
-sub FETCHSIZE { scalar @{$_[0]} }
-sub STORESIZE { $#{$_[0]} = $_[1]-1 }
-sub STORE { $_[0]->[$_[1]] = $_[2] }
-sub FETCH { $_[0]->[$_[1]] }
-sub CLEAR { @{$_[0]} = () }
-sub POP { pop(@{$_[0]}) }
-sub PUSH { my $o = shift; push(@$o,@_) }
-sub SHIFT { shift(@{$_[0]}) }
-sub UNSHIFT { my $o = shift; unshift(@$o,@_) }
-sub EXISTS { exists $_[0]->[$_[1]] }
-sub DELETE { delete $_[0]->[$_[1]] }
-
-sub SPLICE
-{
- my $ob = shift;
- my $sz = $ob->FETCHSIZE;
- my $off = @_ ? shift : 0;
- $off += $sz if $off < 0;
- my $len = @_ ? shift : $sz-$off;
- return splice(@$ob,$off,$len,@_);
-}
-
1;
__END__
@@ -119,8 +84,7 @@ Tie::Array - base class for tied arrays
=head1 SYNOPSIS
package Tie::NewArray;
- use Tie::Array;
- @ISA = ('Tie::Array');
+ use parent 'Tie::Array';
# mandatory methods
sub TIEARRAY { ... }
@@ -142,37 +106,21 @@ Tie::Array - base class for tied arrays
sub EXTEND { ... }
sub DESTROY { ... }
- package Tie::NewStdArray;
- use Tie::Array;
-
- @ISA = ('Tie::StdArray');
-
- # all methods provided by default
-
package main;
$object = tie @somearray,'Tie::NewArray';
- $object = tie @somearray,'Tie::StdArray';
- $object = tie @somearray,'Tie::NewStdArray';
-
=head1 DESCRIPTION
This module provides methods for array-tying classes. See
L<perltie> for a list of the functions required in order to tie an array
-to a package. The basic B<Tie::Array> package provides stub C<DESTROY>,
-and C<EXTEND> methods that do nothing, stub C<DELETE> and C<EXISTS>
-methods that croak() if the delete() or exists() builtins are ever called
-on the tied array, and implementations of C<PUSH>, C<POP>, C<SHIFT>,
+to a package. The basic B<Tie::Array> package provides a stub
+C<EXTEND> method that does nothing,
+and implementations of C<PUSH>, C<POP>, C<SHIFT>,
C<UNSHIFT>, C<SPLICE> and C<CLEAR> in terms of basic C<FETCH>, C<STORE>,
C<FETCHSIZE>, C<STORESIZE>.
-The B<Tie::StdArray> package provides efficient methods required for tied arrays
-which are implemented as blessed references to an "inner" perl array.
-It inherits from B<Tie::Array>, and should cause tied arrays to behave exactly
-like standard arrays, allowing for selective overloading of methods.
-
For developers wishing to write their own tied arrays, the required methods
are briefly defined below. See the L<perltie> section for more detailed
descriptive, as well as example code:
@@ -270,6 +218,18 @@ Returns a list of the original I<length>
=back
+=head1 CHANGES
+
+C<Tie::Array> up to version 1.07 had an unnecessarily complex setup
+of C<TIEARRAY()> and C<new()>. To inherit from C<Tie::Array>, just add
+a C<TIEARRAY()> constructor to your class. If your code used C<new()>, just
+rename it to C<TIEARRAY()>. C<new()> is gone, and so are C<Carp> and
+C<warnings::register>.
+
+C<Tie::StdArray> was included in C<Tie::Array> up to version 1.07. Now,
+it is a properly separated classes. C<Tie::Array> still loads it to avoid
+breaking code.
+
=head1 CAVEATS
There is no support at present for tied @ISA. There is a potential conflict
diff -pNaur perl-5.28.0.orig/lib/Tie/ExtraHash.pm perl-5.28.0/lib/Tie/ExtraHash.pm
--- perl-5.28.0.orig/lib/Tie/ExtraHash.pm 1970-01-01 01:00:00.000000000 +0100
+++ perl-5.28.0/lib/Tie/ExtraHash.pm 2018-09-16 18:01:49.062782093 +0200
@@ -0,0 +1,100 @@
+package Tie::ExtraHash;
+
+use strict;
+use warnings;
+use parent 'Tie::Hash'; # allow for new methods in future versions of perl
+
+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
+
+
+This module provides some skeletal methods for hash-tying classes,
+behaving exactly like standard hashes
+and allows for selective overwriting of methods.
+See L<perltie> for a list of the functions required in order to tie a hash
+to a package.
+
+For developers wishing to write their own tied hashes, the required methods
+are briefly defined in L<Tie::Hash>. See the L<perltie> section for more detailed
+descriptive, as well as example code.
+
+=head1 Inheriting from B<Tie::ExtraHash>
+
+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<gt>[0]>. Thus overwritten
+C<TIEHASH> 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 parent 'Tie::ExtraHash';
+
+ sub TIEHASH {
+ my $class = shift;
+ my $self = bless [{}, @_], $class;
+ warn "New ReportHash created, stored in $sself.\n";
+ $self;
+ }
+ sub STORE {
+ warn "Storing data with key $_[1] at $_[0].\n";
+ $_[0][0]{$_[1]} = $_[2]
+ }
+
+The default C<TIEHASH> method stores "extra" arguments to tie() starting
+from offset 1 in the array referenced by C<tied(%tiedhash)>; this is the
+same storage algorithm as in TIEHASH subroutine above. Hence, a typical
+package inheriting from B<Tie::ExtraHash> does not need to overwrite this
+method.
+
+=head1 CHANGES
+
+C<Tie::ExtraHash> prior to version 1.06 was hidden in C<Tie::Hash>, and so you
+had to manually load C<Tie::Hash> and manipulate C<@ISA> like this:
+
+ use Tie::Hash;
+ our @ISA=('Tie::ExtraHash');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::ExtraHash';
+
+=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 -pNaur perl-5.28.0.orig/lib/Tie/Hash.pm perl-5.28.0/lib/Tie/Hash.pm
--- perl-5.28.0.orig/lib/Tie/Hash.pm 2018-03-20 21:06:36.000000000 +0100
+++ perl-5.28.0/lib/Tie/Hash.pm 2018-09-16 18:23:34.233034429 +0200
@@ -1,68 +1,38 @@
package Tie::Hash;
-our $VERSION = '1.05';
+use strict;
+use warnings;
+use Tie::StdHash (); # for backwards compatibility
+use Tie::ExtraHash (); # for backwards compatibility
+
+our $VERSION = '1.06';
=head1 NAME
-Tie::Hash, Tie::StdHash, Tie::ExtraHash - base class definitions for tied hashes
+Tie::Hash - base class for tied hashes
=head1 SYNOPSIS
package NewHash;
- require Tie::Hash;
-
- @ISA = qw(Tie::Hash);
+ 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 module provides skeletal methods for hash-tying classes. See
L<perltie> for a list of the functions required in order to tie a hash
-to a package. The basic B<Tie::Hash> package provides a C<new> method, as well
-as methods C<TIEHASH>, C<EXISTS> and C<CLEAR>. The B<Tie::StdHash> and
-B<Tie::ExtraHash> packages
-provide most methods for hashes described in L<perltie> (the exceptions
-are C<UNTIE> and C<DESTROY>). They cause tied hashes to behave exactly like standard hashes,
-and allow for selective overwriting of methods. B<Tie::Hash> grandfathers the
-C<new> method: it is used if C<TIEHASH> is not defined
-in the case a class forgets to include a C<TIEHASH> method.
+to a package. The basic B<Tie::Hash> package provides
+the method C<CLEAR>.
+
+L<Tie::StdHash> implements a class that behaves exactly like standard hashes,
+and allows for selective overwriting of methods.
For developers wishing to write their own tied hashes, the required methods
are briefly defined below. See the L<perltie> section for more detailed
@@ -116,55 +86,6 @@ and B<Tie::ExtraHash> do).
=back
-=head1 Inheriting from B<Tie::StdHash>
-
-The accessor methods assume that the actual storage for the data in the tied
-hash is in the hash referenced by C<tied(%tiedhash)>. Thus overwritten
-C<TIEHASH> method should return a hash reference, and the remaining methods
-should operate on the hash referenced by the first argument:
-
- package ReportHash;
- our @ISA = '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]
- }
-
-
-=head1 Inheriting from B<Tie::ExtraHash>
-
-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<gt>[0]>. Thus overwritten
-C<TIEHASH> 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<TIEHASH> method stores "extra" arguments to tie() starting
-from offset 1 in the array referenced by C<tied(%tiedhash)>; this is the
-same storage algorithm as in TIEHASH subroutine above. Hence, a typical
-package inheriting from B<Tie::ExtraHash> does not need to overwrite this
-method.
-
=head1 C<SCALAR>, C<UNTIE> and C<DESTROY>
The methods C<UNTIE> and C<DESTROY> are not defined in B<Tie::Hash>,
@@ -178,6 +99,18 @@ If needed, these methods should be defin
B<Tie::Hash>, B<Tie::StdHash>, or B<Tie::ExtraHash>. See L<perltie/"SCALAR">
to find out what happens when C<SCALAR> does not exist.
+=head1 CHANGES
+
+C<Tie::Hash> up to version 1.05 had an unnecessarily complex setup
+of C<TIEHASH()> and C<new()>. To inherit from C<Tie::Hash()>, just add
+a C<TIEHASH()> constructor to your class. If your code used C<new()>, just
+rename it to C<TIEHASH()>. C<new()> is gone, and so are C<Carp> and
+C<warnings::register>.
+
+C<Tie::StdHash> and C<Tie::ExtraHash> were included in C<Tie::Hash> up to
+version 1.05. Now, they are properly separated classes. C<Tie::Hash> still
+loads them to avoid breaking code.
+
=head1 MORE INFORMATION
The packages relating to various DBM-related implementations (F<DB_File>,
@@ -187,43 +120,6 @@ good working examples.
=cut
-use Carp;
-use warnings::register;
-
-sub new {
- my $pkg = shift;
- $pkg->TIEHASH(@_);
-}
-
-# Grandfather "new"
-
-sub TIEHASH {
- my $pkg = shift;
- my $pkg_new = $pkg -> can ('new');
-
- if ($pkg_new and $pkg ne __PACKAGE__) {
- my $my_new = __PACKAGE__ -> can ('new');
- if ($pkg_new == $my_new) {
- #
- # Prevent recursion
- #
- croak "$pkg must define either a TIEHASH() or a new() method";
- }
-
- warnings::warnif ("WARNING: calling ${pkg}->new since " .
- "${pkg}->TIEHASH is missing");
- $pkg -> new (@_);
- }
- else {
- croak "$pkg doesn't define a TIEHASH method";
- }
-}
-
-sub EXISTS {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define an EXISTS method";
-}
-
sub CLEAR {
my $self = shift;
my $key = $self->FIRSTKEY(@_);
@@ -238,33 +134,4 @@ sub CLEAR {
}
}
-# 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 -pNaur perl-5.28.0.orig/lib/Tie/Hash.t perl-5.28.0/lib/Tie/Hash.t
--- perl-5.28.0.orig/lib/Tie/Hash.t 2018-03-20 21:06:36.000000000 +0100
+++ perl-5.28.0/lib/Tie/Hash.t 2018-09-16 19:03:33.032814985 +0200
@@ -9,5 +9,5 @@ BEGIN {use_ok( 'Tie::Hash' )};
# these are "abstract virtual" parent methods
for my $method (qw( TIEHASH EXISTS )) {
eval { Tie::Hash->$method() };
- like( $@, qr/doesn't define an? $method/, "croaks on inherited $method()" );
+ like( $@, qr/Can't locate object method "$method"/, "dies on inherited $method()" );
}
diff -pNaur perl-5.28.0.orig/lib/Tie/Scalar.pm perl-5.28.0/lib/Tie/Scalar.pm
--- perl-5.28.0.orig/lib/Tie/Scalar.pm 2018-05-21 10:41:35.000000000 +0200
+++ perl-5.28.0/lib/Tie/Scalar.pm 2018-09-16 19:05:18.345673461 +0200
@@ -1,48 +1,38 @@
package Tie::Scalar;
-our $VERSION = '1.04';
+use strict;
+use warnings;
+use Tie::StdScalar (); # for backwards compatibility
-=head1 NAME
-
-Tie::Scalar, Tie::StdScalar - base class definitions for tied scalars
-
-=head1 SYNOPSIS
+our $VERSION = '1.05';
- package NewScalar;
- require Tie::Scalar;
+1;
- @ISA = qw(Tie::Scalar);
+__END__
- sub FETCH { ... } # Provide a needed method
- sub TIESCALAR { ... } # Overrides inherited method
+=head1 NAME
+Tie::Scalar - base class for tied scalars
- package NewStdScalar;
- require Tie::Scalar;
+=head1 SYNOPSIS
- @ISA = qw(Tie::StdScalar);
+ package NewScalar;
+ use parent 'Tie::Scalar';
- # All methods provided by default, so define
- # only what needs be overridden
sub FETCH { ... }
+ sub TIESCALAR { ... }
package main;
tie $new_scalar, 'NewScalar';
- tie $new_std_scalar, 'NewStdScalar';
=head1 DESCRIPTION
-This module provides some skeletal methods for scalar-tying classes. See
+This class provides some skeletal methods for scalar-tying classes. See
L<perltie> for a list of the functions required in tying a scalar to a
-package. The basic B<Tie::Scalar> package provides a C<new> method, as well
-as methods C<TIESCALAR>, C<FETCH> and C<STORE>. The B<Tie::StdScalar>
-package provides all the methods specified in L<perltie>. It inherits from
-B<Tie::Scalar> and causes scalars tied to it to behave exactly like the
-built-in scalars, allowing for selective overloading of methods. The C<new>
-method is provided as a means of grandfathering, for classes that forget to
-provide their own C<TIESCALAR> method.
+package. The basic B<Tie::Scalar> package currently provides no methods,
+but may do so in future versions.
For developers wishing to write their own tied-scalar classes, the methods
are summarized below. The L<perltie> section not only documents these, but
@@ -76,16 +66,22 @@ destruction of an instance.
=head2 Tie::Scalar vs Tie::StdScalar
-C<< Tie::Scalar >> provides all the necessary methods, but one should realize
-they do not do anything useful. Calling C<< Tie::Scalar::FETCH >> or
-C<< Tie::Scalar::STORE >> results in a (trappable) croak. And if you inherit
-from C<< Tie::Scalar >>, you I<must> provide either a C<< new >> or a
-C<< TIESCALAR >> method.
-
If you are looking for a class that does everything for you you don't
define yourself, use the C<< Tie::StdScalar >> class, not the
C<< Tie::Scalar >> one.
+=head1 CHANGES
+
+C<Tie::Scalar> up to version 1.04 had an unnecessarily complex setup
+of C<TIESCALAR()> and C<new()>. To inherit from C<Tie::Scalar>, just add
+a C<TIESCALAR()> constructor to your class. If your code used C<new()>, just
+rename it to C<TIESCALAR()>. C<new()> is gone, and so are C<Carp> and
+C<warnings::register>.
+
+C<Tie::StdScalar> was included in C<Tie::Scalar> up to version 1.04. Now,
+it is a properly separated classes. C<Tie::Scalar> still loads it to avoid
+breaking code.
+
=head1 MORE INFORMATION
The L<perltie> section uses a good example of tying scalars by associating
@@ -93,72 +89,3 @@ process IDs with priority.
=cut
-use Carp;
-use warnings::register;
-
-sub new {
- my $pkg = shift;
- $pkg->TIESCALAR(@_);
-}
-
-# "Grandfather" the new, a la Tie::Hash
-
-sub TIESCALAR {
- my $pkg = shift;
- my $pkg_new = $pkg -> can ('new');
-
- if ($pkg_new and $pkg ne __PACKAGE__) {
- my $my_new = __PACKAGE__ -> can ('new');
- if ($pkg_new == $my_new) {
- #
- # Prevent recursion
- #
- croak "$pkg must define either a TIESCALAR() or a new() method";
- }
-
- warnings::warnif ("WARNING: calling ${pkg}->new since " .
- "${pkg}->TIESCALAR is missing");
- $pkg -> new (@_);
- }
- else {
- croak "$pkg doesn't define a TIESCALAR method";
- }
-}
-
-sub FETCH {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define a FETCH method";
-}
-
-sub STORE {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define a STORE method";
-}
-
-#
-# The Tie::StdScalar package provides scalars that behave exactly like
-# Perl's built-in scalars. Good base to inherit from, if you're only going to
-# tweak a small bit.
-#
-package Tie::StdScalar;
-@ISA = qw(Tie::Scalar);
-
-sub TIESCALAR {
- my $class = shift;
- my $instance = @_ ? shift : undef;
- return bless \$instance => $class;
-}
-
-sub FETCH {
- return ${$_[0]};
-}
-
-sub STORE {
- ${$_[0]} = $_[1];
-}
-
-sub DESTROY {
- undef ${$_[0]};
-}
-
-1;
diff -pNaur perl-5.28.0.orig/lib/Tie/Scalar.t perl-5.28.0/lib/Tie/Scalar.t
--- perl-5.28.0.orig/lib/Tie/Scalar.t 2018-05-21 14:29:23.000000000 +0200
+++ perl-5.28.0/lib/Tie/Scalar.t 2018-09-16 20:04:04.464035128 +0200
@@ -5,35 +5,21 @@ BEGIN {
@INC = '../lib';
}
-# this must come before main, or tests will fail
-package TieTest;
-
-use Tie::Scalar;
-our @ISA = qw( Tie::Scalar );
-
-sub new { 'Fooled you.' }
-
-package main;
-
our $flag;
-use Test::More tests => 16;
+use Test::More tests => 11;
use_ok( 'Tie::Scalar' );
# these are "abstract virtual" parent methods
for my $method (qw( TIESCALAR FETCH STORE )) {
eval { Tie::Scalar->$method() };
- like( $@, qr/doesn't define a $method/, "croaks on inherited $method()" );
+ like( $@, qr/Can't locate object method "$method"/, "dies on inherited $method()" );
}
# the default value is undef
my $scalar = Tie::StdScalar->TIESCALAR();
is( $$scalar, undef, 'used TIESCALAR, default value is still undef' );
-# Tie::StdScalar redirects to TIESCALAR
-$scalar = Tie::StdScalar->new();
-is( $$scalar, undef, 'used new(), default value is still undef' );
-
# this approach should work as well
tie $scalar, 'Tie::StdScalar';
is( $$scalar, undef, 'tied a scalar, default value is undef' );
@@ -60,10 +46,6 @@ local $SIG{__WARN__} = sub {
$warn = $_[0];
};
-# Tie::Scalar::TIEHANDLE should find and call TieTest::new and complain
-is( tie( my $foo, 'TieTest'), 'Fooled you.', 'delegated to new()' );
-like( $warn, qr/WARNING: calling TieTest->new/, 'caught warning fine' );
-
package DestroyAction;
sub new {
@@ -95,26 +77,7 @@ package main;
eval {tie my $foo => "NoMethods";};
like $@ =>
- qr /\QNoMethods must define either a TIESCALAR() or a new() method/,
- "croaks if both new() and TIESCALAR() are missing";
+ qr /Can't locate object method "TIESCALAR"/,
+ "croaks if TIESCALAR() is missing";
};
-#
-# Don't croak on missing new/TIESCALAR if you're inheriting one.
-#
-my $called1 = 0;
-my $called2 = 0;
-
-sub HasMethod1::new {$called1 ++}
- @HasMethod1::ISA = qw [Tie::Scalar];
- @InheritHasMethod1::ISA = qw [HasMethod1];
-
-sub HasMethod2::TIESCALAR {$called2 ++}
- @HasMethod2::ISA = qw [Tie::Scalar];
- @InheritHasMethod2::ISA = qw [HasMethod2];
-
-my $r1 = eval {tie my $foo => "InheritHasMethod1"; 1};
-my $r2 = eval {tie my $foo => "InheritHasMethod2"; 1};
-
-ok $r1 && $called1, "inheriting new() does not croak";
-ok $r2 && $called2, "inheriting TIESCALAR() does not croak";
diff -pNaur perl-5.28.0.orig/lib/Tie/StdArray.pm perl-5.28.0/lib/Tie/StdArray.pm
--- perl-5.28.0.orig/lib/Tie/StdArray.pm 1970-01-01 01:00:00.000000000 +0100
+++ perl-5.28.0/lib/Tie/StdArray.pm 2018-09-16 18:02:03.173763240 +0200
@@ -0,0 +1,88 @@
+package Tie::StdArray;
+
+use 5.006_001;
+use strict;
+use warnings;
+use parent 'Tie::Array'; # inherit EXTEND() and future methods
+
+our $VERSION = '1.08';
+
+sub TIEARRAY { bless [], $_[0] }
+sub FETCHSIZE { scalar @{$_[0]} }
+sub STORESIZE { $#{$_[0]} = $_[1]-1 }
+sub STORE { $_[0]->[$_[1]] = $_[2] }
+sub FETCH { $_[0]->[$_[1]] }
+sub CLEAR { @{$_[0]} = () }
+sub POP { pop(@{$_[0]}) }
+sub PUSH { my $o = shift; push(@$o,@_) }
+sub SHIFT { shift(@{$_[0]}) }
+sub UNSHIFT { my $o = shift; unshift(@$o,@_) }
+sub EXISTS { exists $_[0]->[$_[1]] }
+sub DELETE { delete $_[0]->[$_[1]] }
+
+sub SPLICE
+{
+ my $ob = shift;
+ my $sz = $ob->FETCHSIZE;
+ my $off = @_ ? shift : 0;
+ $off += $sz if $off < 0;
+ my $len = @_ ? shift : $sz-$off;
+ return splice(@$ob,$off,$len,@_);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Tie::StdArray - base class for tied arrays
+
+=head1 SYNOPSIS
+
+ package Tie::NewStdArray;
+ use parent 'Tie::StdArray';
+
+ # all methods provided by default
+
+ package main;
+
+ $object = tie @somearray,'Tie::StdArray';
+ $object = tie @somearray,'Tie::NewStdArray';
+
+
+
+=head1 DESCRIPTION
+
+The B<Tie::StdArray> package provides efficient methods required for tied arrays
+which are implemented as blessed references to an "inner" perl array.
+It inherits from L<Tie::Array>, and should cause tied arrays to behave exactly
+like standard arrays, allowing for selective overloading of methods.
+
+For developers wishing to write their own tied arrays, the required methods
+are briefly defined in C<Tie::Array>. See the L<perltie> section for more detailed
+descriptive, as well as example code.
+
+=head1 CHANGES
+
+C<Tie::StdArray> prior to version 1.08 was hidden in C<Tie::Array>, and so you
+had to manually load C<Tie::Array> and manipulate C<@ISA> like this:
+
+ use Tie::Array;
+ our @ISA=('Tie::StdArray');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::StdArray';
+
+=head1 CAVEATS
+
+There is no support at present for tied @ISA. There is a potential conflict
+between magic entries needed to notice setting of @ISA, and those needed to
+implement 'tie'.
+
+=head1 AUTHOR
+
+Nick Ing-Simmons E<lt>nik@tiuk.ti.comE<gt>
+
+=cut
diff -pNaur perl-5.28.0.orig/lib/Tie/StdHandle.pm perl-5.28.0/lib/Tie/StdHandle.pm
--- perl-5.28.0.orig/lib/Tie/StdHandle.pm 2018-05-21 14:29:23.000000000 +0200
+++ perl-5.28.0/lib/Tie/StdHandle.pm 2018-09-16 18:17:30.411522328 +0200
@@ -1,10 +1,10 @@
package Tie::StdHandle;
use strict;
+use warnings;
+use parent 'Tie::Handle';
-use Tie::Handle;
-our @ISA = 'Tie::Handle';
-our $VERSION = '4.5';
+our $VERSION = '4.6';
=head1 NAME
@@ -13,9 +13,7 @@ Tie::StdHandle - base class definitions
=head1 SYNOPSIS
package NewHandle;
- require Tie::Handle;
-
- @ISA = qw(Tie::Handle);
+ use parent 'Tie::StdHandle';
sub READ { ... } # Provide a needed method
sub TIEHANDLE { ... } # Overrides inherited method
diff -pNaur perl-5.28.0.orig/lib/Tie/StdHash.pm perl-5.28.0/lib/Tie/StdHash.pm
--- perl-5.28.0.orig/lib/Tie/StdHash.pm 1970-01-01 01:00:00.000000000 +0100
+++ perl-5.28.0/lib/Tie/StdHash.pm 2018-09-16 18:01:50.442780249 +0200
@@ -0,0 +1,85 @@
+package Tie::StdHash;
+
+use strict;
+use warnings;
+use parent 'Tie::Hash'; # allow for new methods in future versions of perl
+
+our $VERSION = '1.06';
+
+=head1 NAME
+
+Tie::StdHash - base class for tied hashes
+
+=head1 SYNOPSIS
+
+ package NewStdHash;
+
+ use paremt '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
+
+This module provides some skeletal methods for hash-tying classes,
+behaving exactly like standard hashes
+and allows for selective overwriting of methods.
+See L<perltie> for a list of the functions required in order to tie a hash
+to a package.
+
+For developers wishing to write their own tied hashes, the required methods
+are briefly defined in L<Tie::Hash>. See the L<perltie> section for more detailed
+descriptive, as well as example code.
+
+=head1 Inheriting from B<Tie::StdHash>
+
+The accessor methods assume that the actual storage for the data in the tied
+hash is in the hash referenced by C<tied(%tiedhash)>. Thus overwritten
+C<TIEHASH> method should return a hash reference, and the remaining methods
+should operate on the hash referenced by the first argument:
+
+ package ReportHash;
+ use parent 'Tie::StdHash';
+
+ sub TIEHASH {
+ my $sself = bless {}, shift;
+ warn "New ReportHash created, stored in $sself.\n";
+ $self
+ }
+ sub STORE {
+ warn "Storing data with key $_[1] at $_[0].\n";
+ $_[0]{$_[1]} = $_[2]
+ }
+
+=head1 CHANGES
+
+C<Tie::StdHash> prior to version 1.06 was hidden in C<Tie::Hash>, and so you
+had to manually load C<Tie::Hash> and manipulate C<@ISA> like this:
+
+ use Tie::Hash;
+ our @ISA=('Tie::StdHash');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::StdHash';
+
+=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;
diff -pNaur perl-5.28.0.orig/lib/Tie/StdScalar.pm perl-5.28.0/lib/Tie/StdScalar.pm
--- perl-5.28.0.orig/lib/Tie/StdScalar.pm 1970-01-01 01:00:00.000000000 +0100
+++ perl-5.28.0/lib/Tie/StdScalar.pm 2018-09-16 19:05:06.887688859 +0200
@@ -0,0 +1,134 @@
+package Tie::StdScalar;
+
+use strict;
+use warnings;
+use parent 'Tie::Scalar';
+
+our $VERSION = '1.05';
+
+sub TIESCALAR {
+ my $class = shift;
+ my $instance = @_ ? shift : undef;
+ return bless \$instance => $class;
+}
+
+sub FETCH {
+ return ${$_[0]};
+}
+
+sub STORE {
+ ${$_[0]} = $_[1];
+}
+
+sub DESTROY {
+ undef ${$_[0]};
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Tie::StdScalar - base class for tied scalars
+
+=head1 SYNOPSIS
+
+ package NewScalar;
+ require Tie::Scalar;
+
+ @ISA = qw(Tie::Scalar);
+
+ sub FETCH { ... } # Provide a needed method
+ sub TIESCALAR { ... } # Overrides inherited method
+
+
+ package NewStdScalar;
+ require Tie::Scalar;
+
+ @ISA = qw(Tie::StdScalar);
+
+ # All methods provided by default, so define
+ # only what needs be overridden
+ sub FETCH { ... }
+
+
+ package main;
+
+ tie $new_scalar, 'NewScalar';
+ tie $new_std_scalar, 'NewStdScalar';
+
+=head1 DESCRIPTION
+
+This module provides some skeletal methods for scalar-tying classes. See
+L<perltie> for a list of the functions required in tying a scalar to a
+package. The basic B<Tie::Scalar> package provides a C<new> method, as well
+as methods C<TIESCALAR>, C<FETCH> and C<STORE>. The B<Tie::StdScalar>
+package provides all the methods specified in L<perltie>. It inherits from
+B<Tie::Scalar> and causes scalars tied to it to behave exactly like the
+built-in scalars, allowing for selective overloading of methods. The C<new>
+method is provided as a means of grandfathering, for classes that forget to
+provide their own C<TIESCALAR> method.
+
+For developers wishing to write their own tied-scalar classes, the methods
+are summarized below. The L<perltie> section not only documents these, but
+has sample code as well:
+
+=over 4
+
+=item TIESCALAR classname, LIST
+
+The method invoked by the command C<tie $scalar, classname>. Associates a new
+scalar instance with the specified class. C<LIST> would represent additional
+arguments (along the lines of L<AnyDBM_File> and compatriots) needed to
+complete the association.
+
+=item FETCH this
+
+Retrieve the value of the tied scalar referenced by I<this>.
+
+=item STORE this, value
+
+Store data I<value> in the tied scalar referenced by I<this>.
+
+=item DESTROY this
+
+Free the storage associated with the tied scalar referenced by I<this>.
+This is rarely needed, as Perl manages its memory quite well. But the
+option exists, should a class wish to perform specific actions upon the
+destruction of an instance.
+
+=back
+
+=head2 Tie::Scalar vs Tie::StdScalar
+
+C<< Tie::Scalar >> provides all the necessary methods, but one should realize
+they do not do anything useful. Calling C<< Tie::Scalar::FETCH >> or
+C<< Tie::Scalar::STORE >> results in a (trappable) croak. And if you inherit
+from C<< Tie::Scalar >>, you I<must> provide either a C<< new >> or a
+C<< TIESCALAR >> method.
+
+If you are looking for a class that does everything for you you don't
+define yourself, use the C<< Tie::StdScalar >> class, not the
+C<< Tie::Scalar >> one.
+
+=head1 CHANGES
+
+C<Tie::StdScalar> prior to version 1.05 was hidden in C<Tie::Scalar>, and so you
+had to manually load C<Tie::Scalar> and manipulate C<@ISA> like this:
+
+ use Tie::Scalar;
+ our @ISA=('Tie::StdScalar');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::StdScalar';
+
+=head1 MORE INFORMATION
+
+The L<perltie> section uses a good example of tying scalars by associating
+process IDs with priority.
+
+=cut
+
+
|
From @xsawyerxThank you for the patch! It's a bit harder to review because you include different types of Could you specify what the behavior would be for those that still load On 09/29/2018 07:26 PM, (via RT) wrote:
|
The RT System itself - Status changed from 'new' to 'open' |
From alexander@foken.deHi, On 05.10.2018 16:16, Sawyer X via RT wrote:
OK. I'll split the patch into smaller parts, but that will take a little
The user-visible behaviour should be unchanged. The Tie::Xxx classes Of course, there will be new entires for Tie/StdXxx.pm in %INC, but that That's for the splitting part of the patch, that moves Tie::StdXxx The cleanup part removes the new() constructor. That sounds quite drastic, but I don't expect that to break much code.
The only code that I know to break is lib/Tie/Scalar.t in perl-5.28.0, Code that inherits from Tie::Hash and implements a new() instead of a The same is true for code inheriting for Tie::Scalar, implementing new() Tie::Array does not have a Tie::Array::TIEARRAY() method at all, so
Moving the Tie::StdXxx classes into their own files should not break any Removing the new() constructor will cause a runtime error in code that To be compatible even with that code, I would still remove sub TIEHASH { my $pkg=shift; $pkg->can('new') or die "$pkg does not implement TIEHASH()"; warn "$pkg does not implement TIEHASH(), falling back to new()"; return $pkg->new(@_); } Regards Alexander
-- |
From alexander@foken.deHi, here is essentially the same patch again, spread over seven diff files. 01-cleanup-Tie-Array.diff - removes DESTROY(), EXISTS(), DELETE() from Applied in order, all patches apply cleanly on 5.28.0, no tests fail The three *-cleanup-* patches 01, 02, and 03 ... Overall, these three patches change the error messages generated by This should not break any code that did not warn before. It may break Patch 04 fixes the POD and replaces @ISA with use parent. This should have no visible difference except for parent being loaded. The three *-separate-* patches 05, 06, 07 move the Tie::Std* and Again, this should have no visible difference except for parent and a use parent 'Tie::StdHash', use parent 'Tie::StdArray', use parent Regards, On 05.10.2018 16:16, Sawyer X via RT wrote:
-- |
From alexander@foken.de01-cleanup-Tie-Array.diffdiff -pNaur 00-orig/lib/Tie/Array.pm 01-cleanup-Tie-Array/lib/Tie/Array.pm
--- 00-orig/lib/Tie/Array.pm 2018-05-21 14:29:23.000000000 +0200
+++ 01-cleanup-Tie-Array/lib/Tie/Array.pm 2018-10-21 12:15:45.113927785 +0200
@@ -2,12 +2,10 @@ package Tie::Array;
use 5.006_001;
use strict;
-use Carp;
-our $VERSION = '1.07';
+our $VERSION = '1.08';
# Pod documentation after __END__ below.
-sub DESTROY { }
sub EXTEND { }
sub UNSHIFT { scalar shift->SPLICE(0,0,@_) }
sub SHIFT { shift->SPLICE(0,1) }
@@ -72,16 +70,6 @@ sub SPLICE {
return wantarray ? @result : pop @result;
}
-sub EXISTS {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define an EXISTS method";
-}
-
-sub DELETE {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define a DELETE method";
-}
-
package Tie::StdArray;
our @ISA = 'Tie::Array';
@@ -161,10 +149,9 @@ Tie::Array - base class for tied arrays
This module provides methods for array-tying classes. See
L<perltie> for a list of the functions required in order to tie an array
-to a package. The basic B<Tie::Array> package provides stub C<DESTROY>,
-and C<EXTEND> methods that do nothing, stub C<DELETE> and C<EXISTS>
-methods that croak() if the delete() or exists() builtins are ever called
-on the tied array, and implementations of C<PUSH>, C<POP>, C<SHIFT>,
+to a package. The basic B<Tie::Array> package provides a stub
+C<EXTEND> method that does nothing,
+and implementations of C<PUSH>, C<POP>, C<SHIFT>,
C<UNSHIFT>, C<SPLICE> and C<CLEAR> in terms of basic C<FETCH>, C<STORE>,
C<FETCHSIZE>, C<STORESIZE>.
@@ -233,10 +220,6 @@ The B<Tie::Array> implementation is a st
Clear (remove, delete, ...) all values from the tied array associated with
object I<this>.
-=item DESTROY this
-
-Normal object destructor method.
-
=item PUSH this, LIST
Append elements of LIST to the array.
@@ -270,6 +253,14 @@ Returns a list of the original I<length>
=back
+=head1 CHANGES
+
+C<Tie::Array> up to version 1.07 had an unnecessarily complex setup
+of C<TIEARRAY()> and C<new()>. To inherit from C<Tie::Array>, just add
+a C<TIEARRAY()> constructor to your class. If your code used C<new()>, just
+rename it to C<TIEARRAY()>. C<new()> is gone, and so are C<Carp> and
+C<warnings::register>.
+
=head1 CAVEATS
There is no support at present for tied @ISA. There is a potential conflict
|
From alexander@foken.de02-cleanup-Tie-Hash.diffdiff -pNaur 01-cleanup-Tie-Array/lib/Tie/Hash.pm 02-cleanup-Tie-Hash/lib/Tie/Hash.pm
--- 01-cleanup-Tie-Array/lib/Tie/Hash.pm 2018-03-20 21:06:36.000000000 +0100
+++ 02-cleanup-Tie-Hash/lib/Tie/Hash.pm 2018-10-20 14:45:01.047131547 +0200
@@ -1,6 +1,9 @@
package Tie::Hash;
-our $VERSION = '1.05';
+use strict;
+use warnings;
+
+our $VERSION = '1.06';
=head1 NAME
@@ -9,7 +12,7 @@ Tie::Hash, Tie::StdHash, Tie::ExtraHash
=head1 SYNOPSIS
package NewHash;
- require Tie::Hash;
+ reqzure Tie::Hash;
@ISA = qw(Tie::Hash);
@@ -53,16 +56,15 @@ Tie::Hash, Tie::StdHash, Tie::ExtraHash
=head1 DESCRIPTION
-This module provides some skeletal methods for hash-tying classes. See
+This module provides skeletal methods for hash-tying classes. See
L<perltie> for a list of the functions required in order to tie a hash
-to a package. The basic B<Tie::Hash> package provides a C<new> method, as well
-as methods C<TIEHASH>, C<EXISTS> and C<CLEAR>. The B<Tie::StdHash> and
-B<Tie::ExtraHash> packages
+to a package. The basic B<Tie::Hash> package provides
+the method C<CLEAR()>.
+
+The B<Tie::StdHash> and B<Tie::ExtraHash> packages
provide most methods for hashes described in L<perltie> (the exceptions
are C<UNTIE> and C<DESTROY>). They cause tied hashes to behave exactly like standard hashes,
-and allow for selective overwriting of methods. B<Tie::Hash> grandfathers the
-C<new> method: it is used if C<TIEHASH> is not defined
-in the case a class forgets to include a C<TIEHASH> method.
+and allow for selective overwriting of methods.
For developers wishing to write their own tied hashes, the required methods
are briefly defined below. See the L<perltie> section for more detailed
@@ -178,6 +180,14 @@ If needed, these methods should be defin
B<Tie::Hash>, B<Tie::StdHash>, or B<Tie::ExtraHash>. See L<perltie/"SCALAR">
to find out what happens when C<SCALAR> does not exist.
+=head1 CHANGES
+
+C<Tie::Hash> up to version 1.05 had an unnecessarily complex setup
+of C<TIEHASH()> and C<new()>. To inherit from C<Tie::Hash()>, just add
+a C<TIEHASH()> constructor to your class. If your code used C<new()>, just
+rename it to C<TIEHASH()>. C<new()> is gone, and so are C<Carp> and
+C<warnings::register>.
+
=head1 MORE INFORMATION
The packages relating to various DBM-related implementations (F<DB_File>,
@@ -187,43 +197,6 @@ good working examples.
=cut
-use Carp;
-use warnings::register;
-
-sub new {
- my $pkg = shift;
- $pkg->TIEHASH(@_);
-}
-
-# Grandfather "new"
-
-sub TIEHASH {
- my $pkg = shift;
- my $pkg_new = $pkg -> can ('new');
-
- if ($pkg_new and $pkg ne __PACKAGE__) {
- my $my_new = __PACKAGE__ -> can ('new');
- if ($pkg_new == $my_new) {
- #
- # Prevent recursion
- #
- croak "$pkg must define either a TIEHASH() or a new() method";
- }
-
- warnings::warnif ("WARNING: calling ${pkg}->new since " .
- "${pkg}->TIEHASH is missing");
- $pkg -> new (@_);
- }
- else {
- croak "$pkg doesn't define a TIEHASH method";
- }
-}
-
-sub EXISTS {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define an EXISTS method";
-}
-
sub CLEAR {
my $self = shift;
my $key = $self->FIRSTKEY(@_);
diff -pNaur 01-cleanup-Tie-Array/lib/Tie/Hash.t 02-cleanup-Tie-Hash/lib/Tie/Hash.t
--- 01-cleanup-Tie-Array/lib/Tie/Hash.t 2018-03-20 21:06:36.000000000 +0100
+++ 02-cleanup-Tie-Hash/lib/Tie/Hash.t 2018-10-20 13:40:25.232072765 +0200
@@ -9,5 +9,5 @@ BEGIN {use_ok( 'Tie::Hash' )};
# these are "abstract virtual" parent methods
for my $method (qw( TIEHASH EXISTS )) {
eval { Tie::Hash->$method() };
- like( $@, qr/doesn't define an? $method/, "croaks on inherited $method()" );
+ like( $@, qr/Can't locate object method "$method"/, "dies on inherited $method()" );
}
|
From alexander@foken.de03-cleanup-Tie-Scalar.diffdiff -pNaur 02-cleanup-Tie-Hash/lib/Tie/Scalar.pm 03-cleanup-Tie-Scalar/lib/Tie/Scalar.pm
--- 02-cleanup-Tie-Hash/lib/Tie/Scalar.pm 2018-05-21 10:41:35.000000000 +0200
+++ 03-cleanup-Tie-Scalar/lib/Tie/Scalar.pm 2018-10-20 14:19:42.620103730 +0200
@@ -1,6 +1,8 @@
package Tie::Scalar;
-our $VERSION = '1.04';
+use strict;
+use warnings;
+our $VERSION = '1.05';
=head1 NAME
@@ -34,7 +36,7 @@ Tie::Scalar, Tie::StdScalar - base class
=head1 DESCRIPTION
-This module provides some skeletal methods for scalar-tying classes. See
+This class provides skeletal methods for scalar-tying classes. See
L<perltie> for a list of the functions required in tying a scalar to a
package. The basic B<Tie::Scalar> package provides a C<new> method, as well
as methods C<TIESCALAR>, C<FETCH> and C<STORE>. The B<Tie::StdScalar>
@@ -44,6 +46,9 @@ built-in scalars, allowing for selective
method is provided as a means of grandfathering, for classes that forget to
provide their own C<TIESCALAR> method.
+The baisc C<Tie::Scalar> class currently provides no methods,
+but may do so in a future version.
+
For developers wishing to write their own tied-scalar classes, the methods
are summarized below. The L<perltie> section not only documents these, but
has sample code as well:
@@ -86,6 +91,14 @@ If you are looking for a class that does
define yourself, use the C<< Tie::StdScalar >> class, not the
C<< Tie::Scalar >> one.
+=head1 CHANGES
+
+C<Tie::Scalar> up to version 1.04 had an unnecessarily complex setup
+of C<TIESCALAR()> and C<new()>. To inherit from C<Tie::Scalar>, just add
+a C<TIESCALAR()> constructor to your class. If your code used C<new()>, just
+rename it to C<TIESCALAR()>. C<new()> is gone, and so are C<Carp> and
+C<warnings::register>.
+
=head1 MORE INFORMATION
The L<perltie> section uses a good example of tying scalars by associating
@@ -93,55 +106,13 @@ process IDs with priority.
=cut
-use Carp;
-use warnings::register;
-
-sub new {
- my $pkg = shift;
- $pkg->TIESCALAR(@_);
-}
-
-# "Grandfather" the new, a la Tie::Hash
-
-sub TIESCALAR {
- my $pkg = shift;
- my $pkg_new = $pkg -> can ('new');
-
- if ($pkg_new and $pkg ne __PACKAGE__) {
- my $my_new = __PACKAGE__ -> can ('new');
- if ($pkg_new == $my_new) {
- #
- # Prevent recursion
- #
- croak "$pkg must define either a TIESCALAR() or a new() method";
- }
-
- warnings::warnif ("WARNING: calling ${pkg}->new since " .
- "${pkg}->TIESCALAR is missing");
- $pkg -> new (@_);
- }
- else {
- croak "$pkg doesn't define a TIESCALAR method";
- }
-}
-
-sub FETCH {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define a FETCH method";
-}
-
-sub STORE {
- my $pkg = ref $_[0];
- croak "$pkg doesn't define a STORE method";
-}
-
#
# The Tie::StdScalar package provides scalars that behave exactly like
# Perl's built-in scalars. Good base to inherit from, if you're only going to
# tweak a small bit.
#
package Tie::StdScalar;
-@ISA = qw(Tie::Scalar);
+our @ISA = qw(Tie::Scalar);
sub TIESCALAR {
my $class = shift;
diff -pNaur 02-cleanup-Tie-Hash/lib/Tie/Scalar.t 03-cleanup-Tie-Scalar/lib/Tie/Scalar.t
--- 02-cleanup-Tie-Hash/lib/Tie/Scalar.t 2018-05-21 14:29:23.000000000 +0200
+++ 03-cleanup-Tie-Scalar/lib/Tie/Scalar.t 2018-10-20 14:03:09.175377674 +0200
@@ -5,35 +5,21 @@ BEGIN {
@INC = '../lib';
}
-# this must come before main, or tests will fail
-package TieTest;
-
-use Tie::Scalar;
-our @ISA = qw( Tie::Scalar );
-
-sub new { 'Fooled you.' }
-
-package main;
-
our $flag;
-use Test::More tests => 16;
+use Test::More tests => 11;
use_ok( 'Tie::Scalar' );
# these are "abstract virtual" parent methods
for my $method (qw( TIESCALAR FETCH STORE )) {
eval { Tie::Scalar->$method() };
- like( $@, qr/doesn't define a $method/, "croaks on inherited $method()" );
+ like( $@, qr/Can't locate object method "$method"/, "dies on inherited $method()" );
}
# the default value is undef
my $scalar = Tie::StdScalar->TIESCALAR();
is( $$scalar, undef, 'used TIESCALAR, default value is still undef' );
-# Tie::StdScalar redirects to TIESCALAR
-$scalar = Tie::StdScalar->new();
-is( $$scalar, undef, 'used new(), default value is still undef' );
-
# this approach should work as well
tie $scalar, 'Tie::StdScalar';
is( $$scalar, undef, 'tied a scalar, default value is undef' );
@@ -60,10 +46,6 @@ local $SIG{__WARN__} = sub {
$warn = $_[0];
};
-# Tie::Scalar::TIEHANDLE should find and call TieTest::new and complain
-is( tie( my $foo, 'TieTest'), 'Fooled you.', 'delegated to new()' );
-like( $warn, qr/WARNING: calling TieTest->new/, 'caught warning fine' );
-
package DestroyAction;
sub new {
@@ -95,26 +77,7 @@ package main;
eval {tie my $foo => "NoMethods";};
like $@ =>
- qr /\QNoMethods must define either a TIESCALAR() or a new() method/,
- "croaks if both new() and TIESCALAR() are missing";
+ qr/Can't locate object method "TIESCALAR"/,
+ "dies if TIESCALAR() is missing";
};
-#
-# Don't croak on missing new/TIESCALAR if you're inheriting one.
-#
-my $called1 = 0;
-my $called2 = 0;
-
-sub HasMethod1::new {$called1 ++}
- @HasMethod1::ISA = qw [Tie::Scalar];
- @InheritHasMethod1::ISA = qw [HasMethod1];
-
-sub HasMethod2::TIESCALAR {$called2 ++}
- @HasMethod2::ISA = qw [Tie::Scalar];
- @InheritHasMethod2::ISA = qw [HasMethod2];
-
-my $r1 = eval {tie my $foo => "InheritHasMethod1"; 1};
-my $r2 = eval {tie my $foo => "InheritHasMethod2"; 1};
-
-ok $r1 && $called1, "inheriting new() does not croak";
-ok $r2 && $called2, "inheriting TIESCALAR() does not croak";
|
From alexander@foken.de04-fix-POD-and-use-parent-in-Tie-StdHandle.diffdiff -pNaur 03-cleanup-Tie-Scalar/lib/Tie/StdHandle.pm 04-fix-POD-and-use-parent-in-Tie-StdHandle/lib/Tie/StdHandle.pm
--- 03-cleanup-Tie-Scalar/lib/Tie/StdHandle.pm 2018-05-21 14:29:23.000000000 +0200
+++ 04-fix-POD-and-use-parent-in-Tie-StdHandle/lib/Tie/StdHandle.pm 2018-10-20 15:16:09.713520918 +0200
@@ -1,10 +1,9 @@
package Tie::StdHandle;
use strict;
+use parent 'Tie::Handle';
-use Tie::Handle;
-our @ISA = 'Tie::Handle';
-our $VERSION = '4.5';
+our $VERSION = '4.6';
=head1 NAME
@@ -13,9 +12,7 @@ Tie::StdHandle - base class definitions
=head1 SYNOPSIS
package NewHandle;
- require Tie::Handle;
-
- @ISA = qw(Tie::Handle);
+ use parent 'Tie::StdHandle';
sub READ { ... } # Provide a needed method
sub TIEHANDLE { ... } # Overrides inherited method
|
From alexander@foken.de05-separate-Tie-StdArray.diffdiff -pNaur 04-fix-POD-and-use-parent-in-Tie-StdHandle/MANIFEST 05-separate-Tie-StdArray/MANIFEST
--- 04-fix-POD-and-use-parent-in-Tie-StdHandle/MANIFEST 2018-05-23 15:29:56.000000000 +0200
+++ 05-separate-Tie-StdArray/MANIFEST 2018-10-20 17:11:38.786361217 +0200
@@ -4755,6 +4755,7 @@ lib/Tie/Hash.pm Base class for tied ha
lib/Tie/Hash.t See if Tie::Hash works
lib/Tie/Scalar.pm Base class for tied scalars
lib/Tie/Scalar.t See if Tie::Scalar works
+lib/Tie/StdArray.pm Tie::StdArray
lib/Tie/StdHandle.pm Tie::StdHandle
lib/Tie/SubstrHash.pm Compact hash for known key, value and table size
lib/Tie/SubstrHash.t Test for Tie::SubstrHash
diff -pNaur 04-fix-POD-and-use-parent-in-Tie-StdHandle/Porting/Maintainers.pl 05-separate-Tie-StdArray/Porting/Maintainers.pl
--- 04-fix-POD-and-use-parent-in-Tie-StdHandle/Porting/Maintainers.pl 2018-06-19 23:15:34.000000000 +0200
+++ 05-separate-Tie-StdArray/Porting/Maintainers.pl 2018-10-20 17:36:28.643336677 +0200
@@ -1411,6 +1411,7 @@ use File::Glob qw(:case);
lib/Tie/Handle/
lib/Tie/Hash.{pm,t}
lib/Tie/Scalar.{pm,t}
+ lib/Tie/StdArray.pm
lib/Tie/StdHandle.pm
lib/Tie/SubstrHash.{pm,t}
lib/Time/gmtime.{pm,t}
diff -pNaur 04-fix-POD-and-use-parent-in-Tie-StdHandle/lib/Tie/Array.pm 05-separate-Tie-StdArray/lib/Tie/Array.pm
--- 04-fix-POD-and-use-parent-in-Tie-StdHandle/lib/Tie/Array.pm 2018-10-21 12:29:11.647660072 +0200
+++ 05-separate-Tie-StdArray/lib/Tie/Array.pm 2018-10-21 12:35:08.443166957 +0200
@@ -2,6 +2,9 @@ package Tie::Array;
use 5.006_001;
use strict;
+use warnings;
+use Tie::StdArray (); # for backwards compatibility
+
our $VERSION = '1.08';
# Pod documentation after __END__ below.
@@ -70,32 +73,6 @@ sub SPLICE {
return wantarray ? @result : pop @result;
}
-package Tie::StdArray;
-our @ISA = 'Tie::Array';
-
-sub TIEARRAY { bless [], $_[0] }
-sub FETCHSIZE { scalar @{$_[0]} }
-sub STORESIZE { $#{$_[0]} = $_[1]-1 }
-sub STORE { $_[0]->[$_[1]] = $_[2] }
-sub FETCH { $_[0]->[$_[1]] }
-sub CLEAR { @{$_[0]} = () }
-sub POP { pop(@{$_[0]}) }
-sub PUSH { my $o = shift; push(@$o,@_) }
-sub SHIFT { shift(@{$_[0]}) }
-sub UNSHIFT { my $o = shift; unshift(@$o,@_) }
-sub EXISTS { exists $_[0]->[$_[1]] }
-sub DELETE { delete $_[0]->[$_[1]] }
-
-sub SPLICE
-{
- my $ob = shift;
- my $sz = $ob->FETCHSIZE;
- my $off = @_ ? shift : 0;
- $off += $sz if $off < 0;
- my $len = @_ ? shift : $sz-$off;
- return splice(@$ob,$off,$len,@_);
-}
-
1;
__END__
@@ -107,8 +84,7 @@ Tie::Array - base class for tied arrays
=head1 SYNOPSIS
package Tie::NewArray;
- use Tie::Array;
- @ISA = ('Tie::Array');
+ use parent 'Tie::Array';
# mandatory methods
sub TIEARRAY { ... }
@@ -130,19 +106,9 @@ Tie::Array - base class for tied arrays
sub EXTEND { ... }
sub DESTROY { ... }
- package Tie::NewStdArray;
- use Tie::Array;
-
- @ISA = ('Tie::StdArray');
-
- # all methods provided by default
-
package main;
$object = tie @somearray,'Tie::NewArray';
- $object = tie @somearray,'Tie::StdArray';
- $object = tie @somearray,'Tie::NewStdArray';
-
=head1 DESCRIPTION
@@ -155,11 +121,6 @@ and implementations of C<PUSH>, C<POP>,
C<UNSHIFT>, C<SPLICE> and C<CLEAR> in terms of basic C<FETCH>, C<STORE>,
C<FETCHSIZE>, C<STORESIZE>.
-The B<Tie::StdArray> package provides efficient methods required for tied arrays
-which are implemented as blessed references to an "inner" perl array.
-It inherits from B<Tie::Array>, and should cause tied arrays to behave exactly
-like standard arrays, allowing for selective overloading of methods.
-
For developers wishing to write their own tied arrays, the required methods
are briefly defined below. See the L<perltie> section for more detailed
descriptive, as well as example code:
@@ -261,6 +222,10 @@ a C<TIEARRAY()> constructor to your clas
rename it to C<TIEARRAY()>. C<new()> is gone, and so are C<Carp> and
C<warnings::register>.
+C<Tie::StdArray> was included in C<Tie::Array> up to version 1.07. Now,
+it is a properly separated classes. C<Tie::Array> still loads it to avoid
+breaking code.
+
=head1 CAVEATS
There is no support at present for tied @ISA. There is a potential conflict
diff -pNaur 04-fix-POD-and-use-parent-in-Tie-StdHandle/lib/Tie/StdArray.pm 05-separate-Tie-StdArray/lib/Tie/StdArray.pm
--- 04-fix-POD-and-use-parent-in-Tie-StdHandle/lib/Tie/StdArray.pm 1970-01-01 01:00:00.000000000 +0100
+++ 05-separate-Tie-StdArray/lib/Tie/StdArray.pm 2018-09-16 18:02:03.000000000 +0200
@@ -0,0 +1,88 @@
+package Tie::StdArray;
+
+use 5.006_001;
+use strict;
+use warnings;
+use parent 'Tie::Array'; # inherit EXTEND() and future methods
+
+our $VERSION = '1.08';
+
+sub TIEARRAY { bless [], $_[0] }
+sub FETCHSIZE { scalar @{$_[0]} }
+sub STORESIZE { $#{$_[0]} = $_[1]-1 }
+sub STORE { $_[0]->[$_[1]] = $_[2] }
+sub FETCH { $_[0]->[$_[1]] }
+sub CLEAR { @{$_[0]} = () }
+sub POP { pop(@{$_[0]}) }
+sub PUSH { my $o = shift; push(@$o,@_) }
+sub SHIFT { shift(@{$_[0]}) }
+sub UNSHIFT { my $o = shift; unshift(@$o,@_) }
+sub EXISTS { exists $_[0]->[$_[1]] }
+sub DELETE { delete $_[0]->[$_[1]] }
+
+sub SPLICE
+{
+ my $ob = shift;
+ my $sz = $ob->FETCHSIZE;
+ my $off = @_ ? shift : 0;
+ $off += $sz if $off < 0;
+ my $len = @_ ? shift : $sz-$off;
+ return splice(@$ob,$off,$len,@_);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Tie::StdArray - base class for tied arrays
+
+=head1 SYNOPSIS
+
+ package Tie::NewStdArray;
+ use parent 'Tie::StdArray';
+
+ # all methods provided by default
+
+ package main;
+
+ $object = tie @somearray,'Tie::StdArray';
+ $object = tie @somearray,'Tie::NewStdArray';
+
+
+
+=head1 DESCRIPTION
+
+The B<Tie::StdArray> package provides efficient methods required for tied arrays
+which are implemented as blessed references to an "inner" perl array.
+It inherits from L<Tie::Array>, and should cause tied arrays to behave exactly
+like standard arrays, allowing for selective overloading of methods.
+
+For developers wishing to write their own tied arrays, the required methods
+are briefly defined in C<Tie::Array>. See the L<perltie> section for more detailed
+descriptive, as well as example code.
+
+=head1 CHANGES
+
+C<Tie::StdArray> prior to version 1.08 was hidden in C<Tie::Array>, and so you
+had to manually load C<Tie::Array> and manipulate C<@ISA> like this:
+
+ use Tie::Array;
+ our @ISA=('Tie::StdArray');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::StdArray';
+
+=head1 CAVEATS
+
+There is no support at present for tied @ISA. There is a potential conflict
+between magic entries needed to notice setting of @ISA, and those needed to
+implement 'tie'.
+
+=head1 AUTHOR
+
+Nick Ing-Simmons E<lt>nik@tiuk.ti.comE<gt>
+
+=cut
|
From alexander@foken.de06-separate-Tie-StdHash-ExtraHash.diffdiff -pNaur 05-separate-Tie-StdArray/MANIFEST 06-separate-Tie-StdHash-ExtraHash/MANIFEST
--- 05-separate-Tie-StdArray/MANIFEST 2018-10-20 17:11:38.786361217 +0200
+++ 06-separate-Tie-StdHash-ExtraHash/MANIFEST 2018-10-20 17:14:24.626131548 +0200
@@ -4747,6 +4747,7 @@ lib/Tie/Array/push.t Test for Tie::Arra
lib/Tie/Array/splice.t Test for Tie::Array::SPLICE
lib/Tie/Array/std.t Test for Tie::StdArray
lib/Tie/Array/stdpush.t Test for Tie::StdArray
+lib/Tie/ExtraHash.pm Tie::ExtraHash
lib/Tie/ExtraHash.t Test for Tie::ExtraHash (in Tie/Hash.pm)
lib/Tie/Handle.pm Base class for tied handles
lib/Tie/Handle/stdhandle.t Test for Tie::StdHandle
@@ -4757,6 +4758,7 @@ lib/Tie/Scalar.pm Base class for tied s
lib/Tie/Scalar.t See if Tie::Scalar works
lib/Tie/StdArray.pm Tie::StdArray
lib/Tie/StdHandle.pm Tie::StdHandle
+lib/Tie/StdHash.pm Tie::StdHash
lib/Tie/SubstrHash.pm Compact hash for known key, value and table size
lib/Tie/SubstrHash.t Test for Tie::SubstrHash
lib/Time/gmtime.pm By-name interface to Perl's builtin gmtime
diff -pNaur 05-separate-Tie-StdArray/Porting/Maintainers.pl 06-separate-Tie-StdHash-ExtraHash/Porting/Maintainers.pl
--- 05-separate-Tie-StdArray/Porting/Maintainers.pl 2018-10-20 17:36:28.643336677 +0200
+++ 06-separate-Tie-StdHash-ExtraHash/Porting/Maintainers.pl 2018-10-20 17:39:24.904102700 +0200
@@ -1406,13 +1406,14 @@ use File::Glob qw(:case);
lib/Thread.{pm,t}
lib/Tie/Array.pm
lib/Tie/Array/
- lib/Tie/ExtraHash.t
+ lib/Tie/ExtraHash.{pm,t}
lib/Tie/Handle.pm
lib/Tie/Handle/
lib/Tie/Hash.{pm,t}
lib/Tie/Scalar.{pm,t}
lib/Tie/StdArray.pm
lib/Tie/StdHandle.pm
+ lib/Tie/StdHash.pm
lib/Tie/SubstrHash.{pm,t}
lib/Time/gmtime.{pm,t}
lib/Time/localtime.{pm,t}
diff -pNaur 05-separate-Tie-StdArray/lib/Tie/ExtraHash.pm 06-separate-Tie-StdHash-ExtraHash/lib/Tie/ExtraHash.pm
--- 05-separate-Tie-StdArray/lib/Tie/ExtraHash.pm 1970-01-01 01:00:00.000000000 +0100
+++ 06-separate-Tie-StdHash-ExtraHash/lib/Tie/ExtraHash.pm 2018-09-16 18:01:49.000000000 +0200
@@ -0,0 +1,100 @@
+package Tie::ExtraHash;
+
+use strict;
+use warnings;
+use parent 'Tie::Hash'; # allow for new methods in future versions of perl
+
+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
+
+
+This module provides some skeletal methods for hash-tying classes,
+behaving exactly like standard hashes
+and allows for selective overwriting of methods.
+See L<perltie> for a list of the functions required in order to tie a hash
+to a package.
+
+For developers wishing to write their own tied hashes, the required methods
+are briefly defined in L<Tie::Hash>. See the L<perltie> section for more detailed
+descriptive, as well as example code.
+
+=head1 Inheriting from B<Tie::ExtraHash>
+
+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<gt>[0]>. Thus overwritten
+C<TIEHASH> 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 parent 'Tie::ExtraHash';
+
+ sub TIEHASH {
+ my $class = shift;
+ my $self = bless [{}, @_], $class;
+ warn "New ReportHash created, stored in $sself.\n";
+ $self;
+ }
+ sub STORE {
+ warn "Storing data with key $_[1] at $_[0].\n";
+ $_[0][0]{$_[1]} = $_[2]
+ }
+
+The default C<TIEHASH> method stores "extra" arguments to tie() starting
+from offset 1 in the array referenced by C<tied(%tiedhash)>; this is the
+same storage algorithm as in TIEHASH subroutine above. Hence, a typical
+package inheriting from B<Tie::ExtraHash> does not need to overwrite this
+method.
+
+=head1 CHANGES
+
+C<Tie::ExtraHash> prior to version 1.06 was hidden in C<Tie::Hash>, and so you
+had to manually load C<Tie::Hash> and manipulate C<@ISA> like this:
+
+ use Tie::Hash;
+ our @ISA=('Tie::ExtraHash');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::ExtraHash';
+
+=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 -pNaur 05-separate-Tie-StdArray/lib/Tie/Hash.pm 06-separate-Tie-StdHash-ExtraHash/lib/Tie/Hash.pm
--- 05-separate-Tie-StdArray/lib/Tie/Hash.pm 2018-10-20 14:45:01.047131547 +0200
+++ 06-separate-Tie-StdHash-ExtraHash/lib/Tie/Hash.pm 2018-10-21 12:41:02.402760420 +0200
@@ -2,57 +2,27 @@ package Tie::Hash;
use strict;
use warnings;
+use Tie::StdHash (); # for backwards compatibility
+use Tie::ExtraHash (); # for backwards compatibility
our $VERSION = '1.06';
=head1 NAME
-Tie::Hash, Tie::StdHash, Tie::ExtraHash - base class definitions for tied hashes
+Tie::Hash - base class for tied hashes
=head1 SYNOPSIS
package NewHash;
- reqzure Tie::Hash;
-
- @ISA = qw(Tie::Hash);
+ 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
@@ -61,10 +31,8 @@ L<perltie> for a list of the functions r
to a package. The basic B<Tie::Hash> package provides
the method C<CLEAR()>.
-The B<Tie::StdHash> and B<Tie::ExtraHash> packages
-provide most methods for hashes described in L<perltie> (the exceptions
-are C<UNTIE> and C<DESTROY>). They cause tied hashes to behave exactly like standard hashes,
-and allow for selective overwriting of methods.
+L<Tie::StdHash> implements a class that behaves exactly like standard hashes,
+and allows for selective overwriting of methods.
For developers wishing to write their own tied hashes, the required methods
are briefly defined below. See the L<perltie> section for more detailed
@@ -118,55 +86,6 @@ and B<Tie::ExtraHash> do).
=back
-=head1 Inheriting from B<Tie::StdHash>
-
-The accessor methods assume that the actual storage for the data in the tied
-hash is in the hash referenced by C<tied(%tiedhash)>. Thus overwritten
-C<TIEHASH> method should return a hash reference, and the remaining methods
-should operate on the hash referenced by the first argument:
-
- package ReportHash;
- our @ISA = '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]
- }
-
-
-=head1 Inheriting from B<Tie::ExtraHash>
-
-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<gt>[0]>. Thus overwritten
-C<TIEHASH> 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<TIEHASH> method stores "extra" arguments to tie() starting
-from offset 1 in the array referenced by C<tied(%tiedhash)>; this is the
-same storage algorithm as in TIEHASH subroutine above. Hence, a typical
-package inheriting from B<Tie::ExtraHash> does not need to overwrite this
-method.
-
=head1 C<SCALAR>, C<UNTIE> and C<DESTROY>
The methods C<UNTIE> and C<DESTROY> are not defined in B<Tie::Hash>,
@@ -188,6 +107,10 @@ a C<TIEHASH()> constructor to your class
rename it to C<TIEHASH()>. C<new()> is gone, and so are C<Carp> and
C<warnings::register>.
+C<Tie::StdHash> and C<Tie::ExtraHash> were included in C<Tie::Hash> up to
+version 1.05. Now, they are properly separated classes. C<Tie::Hash> still
+loads them to avoid breaking code.
+
=head1 MORE INFORMATION
The packages relating to various DBM-related implementations (F<DB_File>,
@@ -211,33 +134,4 @@ sub CLEAR {
}
}
-# 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 -pNaur 05-separate-Tie-StdArray/lib/Tie/StdHash.pm 06-separate-Tie-StdHash-ExtraHash/lib/Tie/StdHash.pm
--- 05-separate-Tie-StdArray/lib/Tie/StdHash.pm 1970-01-01 01:00:00.000000000 +0100
+++ 06-separate-Tie-StdHash-ExtraHash/lib/Tie/StdHash.pm 2018-09-16 18:01:50.000000000 +0200
@@ -0,0 +1,85 @@
+package Tie::StdHash;
+
+use strict;
+use warnings;
+use parent 'Tie::Hash'; # allow for new methods in future versions of perl
+
+our $VERSION = '1.06';
+
+=head1 NAME
+
+Tie::StdHash - base class for tied hashes
+
+=head1 SYNOPSIS
+
+ package NewStdHash;
+
+ use paremt '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
+
+This module provides some skeletal methods for hash-tying classes,
+behaving exactly like standard hashes
+and allows for selective overwriting of methods.
+See L<perltie> for a list of the functions required in order to tie a hash
+to a package.
+
+For developers wishing to write their own tied hashes, the required methods
+are briefly defined in L<Tie::Hash>. See the L<perltie> section for more detailed
+descriptive, as well as example code.
+
+=head1 Inheriting from B<Tie::StdHash>
+
+The accessor methods assume that the actual storage for the data in the tied
+hash is in the hash referenced by C<tied(%tiedhash)>. Thus overwritten
+C<TIEHASH> method should return a hash reference, and the remaining methods
+should operate on the hash referenced by the first argument:
+
+ package ReportHash;
+ use parent 'Tie::StdHash';
+
+ sub TIEHASH {
+ my $sself = bless {}, shift;
+ warn "New ReportHash created, stored in $sself.\n";
+ $self
+ }
+ sub STORE {
+ warn "Storing data with key $_[1] at $_[0].\n";
+ $_[0]{$_[1]} = $_[2]
+ }
+
+=head1 CHANGES
+
+C<Tie::StdHash> prior to version 1.06 was hidden in C<Tie::Hash>, and so you
+had to manually load C<Tie::Hash> and manipulate C<@ISA> like this:
+
+ use Tie::Hash;
+ our @ISA=('Tie::StdHash');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::StdHash';
+
+=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;
|
From alexander@foken.de07-separate-Tie-StdScalar.diffdiff -pNaur 06-separate-Tie-StdHash-ExtraHash/MANIFEST 07-separate-Tie-StdScalar/MANIFEST
--- 06-separate-Tie-StdHash-ExtraHash/MANIFEST 2018-10-20 17:14:24.626131548 +0200
+++ 07-separate-Tie-StdScalar/MANIFEST 2018-10-20 17:15:05.814074552 +0200
@@ -4759,6 +4759,7 @@ lib/Tie/Scalar.t See if Tie::Scalar wor
lib/Tie/StdArray.pm Tie::StdArray
lib/Tie/StdHandle.pm Tie::StdHandle
lib/Tie/StdHash.pm Tie::StdHash
+lib/Tie/StdScalar.pm Tie::StdScalar
lib/Tie/SubstrHash.pm Compact hash for known key, value and table size
lib/Tie/SubstrHash.t Test for Tie::SubstrHash
lib/Time/gmtime.pm By-name interface to Perl's builtin gmtime
diff -pNaur 06-separate-Tie-StdHash-ExtraHash/Porting/Maintainers.pl 07-separate-Tie-StdScalar/Porting/Maintainers.pl
--- 06-separate-Tie-StdHash-ExtraHash/Porting/Maintainers.pl 2018-10-20 17:39:24.904102700 +0200
+++ 07-separate-Tie-StdScalar/Porting/Maintainers.pl 2018-10-20 17:39:16.055114474 +0200
@@ -1414,6 +1414,7 @@ use File::Glob qw(:case);
lib/Tie/StdArray.pm
lib/Tie/StdHandle.pm
lib/Tie/StdHash.pm
+ lib/Tie/StdScalar.pm
lib/Tie/SubstrHash.{pm,t}
lib/Time/gmtime.{pm,t}
lib/Time/localtime.{pm,t}
diff -pNaur 06-separate-Tie-StdHash-ExtraHash/lib/Tie/Scalar.pm 07-separate-Tie-StdScalar/lib/Tie/Scalar.pm
--- 06-separate-Tie-StdHash-ExtraHash/lib/Tie/Scalar.pm 2018-10-20 14:19:42.620103730 +0200
+++ 07-separate-Tie-StdScalar/lib/Tie/Scalar.pm 2018-10-21 15:58:06.458230209 +0200
@@ -2,52 +2,37 @@ package Tie::Scalar;
use strict;
use warnings;
+use Tie::StdScalar (); # for backwards compatibility
+
our $VERSION = '1.05';
+1;
+
+__END__
+
=head1 NAME
-Tie::Scalar, Tie::StdScalar - base class definitions for tied scalars
+Tie::Scalar - base class for tied scalars
=head1 SYNOPSIS
package NewScalar;
- require Tie::Scalar;
-
- @ISA = qw(Tie::Scalar);
-
- sub FETCH { ... } # Provide a needed method
- sub TIESCALAR { ... } # Overrides inherited method
-
+ use parent 'Tie::Scalar';
- package NewStdScalar;
- require Tie::Scalar;
-
- @ISA = qw(Tie::StdScalar);
-
- # All methods provided by default, so define
- # only what needs be overridden
sub FETCH { ... }
+ sub TIESCALAR { ... }
package main;
tie $new_scalar, 'NewScalar';
- tie $new_std_scalar, 'NewStdScalar';
=head1 DESCRIPTION
-This class provides skeletal methods for scalar-tying classes. See
+This class provides some skeletal methods for scalar-tying classes. See
L<perltie> for a list of the functions required in tying a scalar to a
-package. The basic B<Tie::Scalar> package provides a C<new> method, as well
-as methods C<TIESCALAR>, C<FETCH> and C<STORE>. The B<Tie::StdScalar>
-package provides all the methods specified in L<perltie>. It inherits from
-B<Tie::Scalar> and causes scalars tied to it to behave exactly like the
-built-in scalars, allowing for selective overloading of methods. The C<new>
-method is provided as a means of grandfathering, for classes that forget to
-provide their own C<TIESCALAR> method.
-
-The baisc C<Tie::Scalar> class currently provides no methods,
-but may do so in a future version.
+package. The basic B<Tie::Scalar> package currently provides no methods,
+but may do so in future versions.
For developers wishing to write their own tied-scalar classes, the methods
are summarized below. The L<perltie> section not only documents these, but
@@ -81,12 +66,6 @@ destruction of an instance.
=head2 Tie::Scalar vs Tie::StdScalar
-C<< Tie::Scalar >> provides all the necessary methods, but one should realize
-they do not do anything useful. Calling C<< Tie::Scalar::FETCH >> or
-C<< Tie::Scalar::STORE >> results in a (trappable) croak. And if you inherit
-from C<< Tie::Scalar >>, you I<must> provide either a C<< new >> or a
-C<< TIESCALAR >> method.
-
If you are looking for a class that does everything for you you don't
define yourself, use the C<< Tie::StdScalar >> class, not the
C<< Tie::Scalar >> one.
@@ -99,6 +78,10 @@ a C<TIESCALAR()> constructor to your cla
rename it to C<TIESCALAR()>. C<new()> is gone, and so are C<Carp> and
C<warnings::register>.
+C<Tie::StdScalar> was included in C<Tie::Scalar> up to version 1.04. Now,
+it is a properly separated classes. C<Tie::Scalar> still loads it to avoid
+breaking code.
+
=head1 MORE INFORMATION
The L<perltie> section uses a good example of tying scalars by associating
@@ -106,30 +89,3 @@ process IDs with priority.
=cut
-#
-# The Tie::StdScalar package provides scalars that behave exactly like
-# Perl's built-in scalars. Good base to inherit from, if you're only going to
-# tweak a small bit.
-#
-package Tie::StdScalar;
-our @ISA = qw(Tie::Scalar);
-
-sub TIESCALAR {
- my $class = shift;
- my $instance = @_ ? shift : undef;
- return bless \$instance => $class;
-}
-
-sub FETCH {
- return ${$_[0]};
-}
-
-sub STORE {
- ${$_[0]} = $_[1];
-}
-
-sub DESTROY {
- undef ${$_[0]};
-}
-
-1;
diff -pNaur 06-separate-Tie-StdHash-ExtraHash/lib/Tie/StdScalar.pm 07-separate-Tie-StdScalar/lib/Tie/StdScalar.pm
--- 06-separate-Tie-StdHash-ExtraHash/lib/Tie/StdScalar.pm 1970-01-01 01:00:00.000000000 +0100
+++ 07-separate-Tie-StdScalar/lib/Tie/StdScalar.pm 2018-10-21 16:04:34.942727434 +0200
@@ -0,0 +1,106 @@
+package Tie::StdScalar;
+
+use strict;
+use warnings;
+use parent 'Tie::Scalar';
+
+our $VERSION = '1.05';
+
+sub TIESCALAR {
+ my $class = shift;
+ my $instance = @_ ? shift : undef;
+ return bless \$instance => $class;
+}
+
+sub FETCH {
+ return ${$_[0]};
+}
+
+sub STORE {
+ ${$_[0]} = $_[1];
+}
+
+sub DESTROY {
+ undef ${$_[0]};
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Tie::StdScalar - base class for tied scalars
+
+=head1 SYNOPSIS
+
+ package NewStdScalar;
+ use parent 'Tie::StdScalar';
+
+ # All methods provided by default, so define
+ # only what needs be overridden
+ sub FETCH { ... }
+
+
+ package main;
+
+ tie $new_std_scalar, 'NewStdScalar';
+
+=head1 DESCRIPTION
+
+This class provides all the methods for scalar-tying classes. See
+L<perltie> for a list of the functions required in tying a scalar to a
+package. It inherits from
+B<Tie::Scalar> and causes scalars tied to it to behave exactly like the
+built-in scalars, allowing for selective overloading of methods.
+
+For developers wishing to write their own tied-scalar classes, the methods
+are summarized below. The L<perltie> section not only documents these, but
+has sample code as well:
+
+=over 4
+
+=item TIESCALAR classname, LIST
+
+The method invoked by the command C<tie $scalar, classname>. Associates a new
+scalar instance with the specified class. C<LIST> would represent additional
+arguments (along the lines of L<AnyDBM_File> and compatriots) needed to
+complete the association.
+
+=item FETCH this
+
+Retrieve the value of the tied scalar referenced by I<this>.
+
+=item STORE this, value
+
+Store data I<value> in the tied scalar referenced by I<this>.
+
+=item DESTROY this
+
+Free the storage associated with the tied scalar referenced by I<this>.
+This is rarely needed, as Perl manages its memory quite well. But the
+option exists, should a class wish to perform specific actions upon the
+destruction of an instance.
+
+=back
+
+=head1 CHANGES
+
+C<Tie::StdScalar> prior to version 1.05 was hidden in C<Tie::Scalar>, and so you
+had to manually load C<Tie::Scalar> and manipulate C<@ISA> like this:
+
+ use Tie::Scalar;
+ our @ISA=('Tie::StdScalar');
+
+And while this still works, new code should do this instead:
+
+ use parent 'Tie::StdScalar';
+
+=head1 MORE INFORMATION
+
+The L<perltie> section uses a good example of tying scalars by associating
+process IDs with priority.
+
+=cut
+
+
|
"The motion fails for lack of a second." There's been no support for these patches since they were filed in 2018. Taking the ticket for the purpose of closing it within 7 days unless someone wants to take the discussion forward. |
I'm not certain that we want all of these changes, but allowing the Tie::Std* packages to be inherited from directly is an improvement. I'll try to turn this into a PR. |
Migrated from rt.perl.org#133551 (status was 'open')
Searchable as RT133551$
The text was updated successfully, but these errors were encountered: