Skip to content
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

Open
p5pRT opened this issue Sep 29, 2018 · 16 comments
Assignees
Labels

Comments

@p5pRT
Copy link

p5pRT commented Sep 29, 2018

Migrated from rt.perl.org#133551 (status was 'open')

Searchable as RT133551$

@p5pRT
Copy link
Author

p5pRT commented Sep 29, 2018

From alexander@foken.de

This is a bug report for perl from alexander@​foken.de,
generated with the help of perlbug 1.41 running under perl 5.28.0.

Can't inherit from Tie​::StdHash, Tie​::StdArray, Tie​::StdScalar via use
parent. Have to load Tie​::Hash, Tie​::Array, Tie​::Scalar first.
Problem is that the Tie​::Std* classes are hidden in Tie/Hash.pm,
Tie/Array.pm, Tie/Scalar.pm.

use parent 'Tie​::StdHandle' works fine because Tie​::StdHandle is
in Tie/StdHandle.pm, as expected.

My patch moves the Tie​::Std* classes to their own files and removes a
lot of unneeded code.

Test case and patch attached.

Longer description starts at <https://perlmonks.org/?node_id=1221954>

First fully working patch against 5.20.0 at
<https://perlmonks.org/?node_id=1222832;showspoiler=1222832-1>


Flags​:
  category=library
  severity=none
  Type=Patch
  PatchStatus=HasPatch
  module=Tie​::Hash


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​:
  Platform​:
  osname=linux
  osvers=4.4.153-foken
  archname=x86_64-linux
  uname='linux teroknor 4.4.153-foken #2 smp sat sep 15 18​:49​:58 cest
2018 x86_64 intel(r) core(tm)2 duo cpu e8500 @​ 3.16ghz genuineintel
gnulinux '
  config_args='-Dmksymlinks -de -Dprefix=/home/alex/perl-source/instdir'
  hint=recommended
  useposix=true
  d_sigaction=define
  useithreads=undef
  usemultiplicity=undef
  use64bitint=define
  use64bitall=define
  uselongdouble=undef
  usemymalloc=n
  default_inc_excludes_dot=define
  bincompat5005=undef
  Compiler​:
  cc='cc'
  ccflags ='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
  optimize='-O2'
  cppflags='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include'
  ccversion=''
  gccversion='5.5.0'
  gccosandvers=''
  intsize=4
  longsize=8
  ptrsize=8
  doublesize=8
  byteorder=12345678
  doublekind=3
  d_longlong=define
  longlongsize=8
  d_longdbl=define
  longdblsize=16
  longdblkind=3
  ivtype='long'
  ivsize=8
  nvtype='double'
  nvsize=8
  Off_t='off_t'
  lseeksize=8
  alignbytes=8
  prototype=define
  Linker and Libraries​:
  ld='cc'
  ldflags =' -fstack-protector-strong -L/usr/local/lib'
  libpth=/usr/local/lib
/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/include-fixed /usr/lib
/lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
  libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
  perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=libc-2.23.so
  so=so
  useshrplib=false
  libperl=libperl.a
  gnulibc_version='2.23'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs
  dlext=so
  d_dlsymun=undef
  ccdlflags='-Wl,-E'
  cccdlflags='-fPIC'
  lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


@​INC for perl 5.28.0​:
  /home/alex/perl-source/instdir/lib/site_perl/5.28.0/x86_64-linux
  /home/alex/perl-source/instdir/lib/site_perl/5.28.0
  /home/alex/perl-source/instdir/lib/5.28.0/x86_64-linux
  /home/alex/perl-source/instdir/lib/5.28.0


Environment for perl 5.28.0​:
  HOME=/home/alex
  LANG=en_US
  LANGUAGE (unset)
  LC_COLLATE=C
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)

PATH=/home/alex​:/command​:/usr/local/bin​:/usr/bin​:/bin​:/usr/games​:/usr/lib64/qt/bin​:/usr/share/texmf/bin
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Sep 29, 2018

From alexander@foken.de

testcase.pl

@p5pRT
Copy link
Author

p5pRT commented Sep 29, 2018

From alexander@foken.de

patch.diff
diff -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
+
+

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2018

From @xsawyerx

Thank you for the patch!

It's a bit harder to review because you include different types of
changes (renaming, clean ups) but made it into a single patch. Having
multiple patches for each change (even if it's only "0001-rename.patch"
and "0002-cleanups.patch") with explanations of what's being done would
make it much easier for us to quickly review this.

Could you specify what the behavior would be for those that still load
Tie​::{Scalar,Array,Hash} to receive the :​:Std version? If your change
breaks older code, it is not suitable for inclusion yet.

On 09/29/2018 07​:26 PM, (via RT) wrote​:

# New Ticket Created by
# Please include the string​: [perl #133551]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=133551 >

This is a bug report for perl from alexander@​foken.de,
generated with the help of perlbug 1.41 running under perl 5.28.0.

Can't inherit from Tie​::StdHash, Tie​::StdArray, Tie​::StdScalar via use
parent. Have to load Tie​::Hash, Tie​::Array, Tie​::Scalar first.
Problem is that the Tie​::Std* classes are hidden in Tie/Hash.pm,
Tie/Array.pm, Tie/Scalar.pm.

use parent 'Tie​::StdHandle' works fine because Tie​::StdHandle is
in Tie/StdHandle.pm, as expected.

My patch moves the Tie​::Std* classes to their own files and removes a
lot of unneeded code.

Test case and patch attached.

Longer description starts at <https://perlmonks.org/?node_id=1221954>

First fully working patch against 5.20.0 at
<https://perlmonks.org/?node_id=1222832;showspoiler=1222832-1>

---
Flags​:
category=library
severity=none
Type=Patch
PatchStatus=HasPatch
module=Tie​::Hash
---
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​:
Platform​:
osname=linux
osvers=4.4.153-foken
archname=x86_64-linux
uname='linux teroknor 4.4.153-foken #2 smp sat sep 15 18​:49​:58 cest
2018 x86_64 intel(r) core(tm)2 duo cpu e8500 @​ 3.16ghz genuineintel
gnulinux '
config_args='-Dmksymlinks -de -Dprefix=/home/alex/perl-source/instdir'
hint=recommended
useposix=true
d_sigaction=define
useithreads=undef
usemultiplicity=undef
use64bitint=define
use64bitall=define
uselongdouble=undef
usemymalloc=n
default_inc_excludes_dot=define
bincompat5005=undef
Compiler​:
cc='cc'
ccflags ='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
optimize='-O2'
cppflags='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include'
ccversion=''
gccversion='5.5.0'
gccosandvers=''
intsize=4
longsize=8
ptrsize=8
doublesize=8
byteorder=12345678
doublekind=3
d_longlong=define
longlongsize=8
d_longdbl=define
longdblsize=16
longdblkind=3
ivtype='long'
ivsize=8
nvtype='double'
nvsize=8
Off_t='off_t'
lseeksize=8
alignbytes=8
prototype=define
Linker and Libraries​:
ld='cc'
ldflags =' -fstack-protector-strong -L/usr/local/lib'
libpth=/usr/local/lib
/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/include-fixed /usr/lib
/lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
libc=libc-2.23.so
so=so
useshrplib=false
libperl=libperl.a
gnulibc_version='2.23'
Dynamic Linking​:
dlsrc=dl_dlopen.xs
dlext=so
d_dlsymun=undef
ccdlflags='-Wl,-E'
cccdlflags='-fPIC'
lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'

---
@​INC for perl 5.28.0​:
/home/alex/perl-source/instdir/lib/site_perl/5.28.0/x86_64-linux
/home/alex/perl-source/instdir/lib/site_perl/5.28.0
/home/alex/perl-source/instdir/lib/5.28.0/x86_64-linux
/home/alex/perl-source/instdir/lib/5.28.0

---
Environment for perl 5.28.0​:
HOME=/home/alex
LANG=en_US
LANGUAGE (unset)
LC_COLLATE=C
LD_LIBRARY_PATH (unset)
LOGDIR (unset)

PATH=/home/alex​:/command​:/usr/local/bin​:/usr/bin​:/bin​:/usr/games​:/usr/lib64/qt/bin​:/usr/share/texmf/bin
PERL_BADLANG (unset)
SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2018

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Oct 8, 2018

From alexander@foken.de

Hi,

On 05.10.2018 16​:16, Sawyer X via RT wrote​:

Thank you for the patch!

It's a bit harder to review because you include different types of
changes (renaming, clean ups) but made it into a single patch. Having
multiple patches for each change (even if it's only "0001-rename.patch"
and "0002-cleanups.patch") with explanations of what's being done would
make it much easier for us to quickly review this.

OK. I'll split the patch into smaller parts, but that will take a little
bit of time. I'm currently a little bit short on free time for Perl.

Could you specify what the behavior would be for those that still load
Tie​::{Scalar,Array,Hash} to receive the :​:Std version?

The user-visible behaviour should be unchanged. The Tie​::Xxx classes
always load Tie​::StdXxx to avoid breaking old code. (See lines 55, 291,
and 540 of my patch.)

Of course, there will be new entires for Tie/StdXxx.pm in %INC, but that
should make no difference.

That's for the splitting part of the patch, that moves Tie​::StdXxx
classes into their own files.

The cleanup part removes the new() constructor.

That sounds quite drastic, but I don't expect that to break much code.
Quoting myself from <https://perlmonks.org/?node_id=1221971>:

For the last 16 years, it seems that nobody complained about
Tie​::StdHash no longer inheriting the useless new() from Tie​::Hash. [...]

Having a fresh look at the code of both Tie​::StdHash and Tie​::Hash
explains why nobody complained​:

* Tie​::Hash​::TIEHASH() is designed to call new() in an inheriting
class, or to be reimplemented by the inheriting class. If the
inheriting class implements neither new() nor TIEHASH(),
Tie​::Hash​::TIEHASH() croak()s.
* If the inheriting class implements new(), but not TIEHASH(),
Tie​::Hash​::TIEHASH() warns that it calls new() because TIEHASH() is
missing. So why even bother to implement new()?
* Tie​::Hash​::new(), which is never called by tie, just calls TIEHASH()
of the inheriting class. Implementing new() in an inheriting class
does not make any sense at all, because you need a class name, not an
object, for tie.
* Tie​::StdHash implements its own TIEHASH(), as expected by Tie​::Hash
and tie. This prevents new() from being called indirectly from tie().

So, no class inheriting from Tie​::StdHash needs a new() implementation.
The same is true for Tie​::Array / Tie​::StdArray and Tie​::Scalar /
Tie​::StdScalar.

The only code that I know to break is lib/Tie/Scalar.t in perl-5.28.0,
because that explicitly tests the useless new() constructor and the
delegation via Tie​::Scalar​::TIESCALAR().

Code that inherits from Tie​::Hash and implements a new() instead of a
TIEHASH() constructor has generated a warning from Tie​::Hash​::TIEHASH()
("WARNING​: calling ${pkg}->new since ${pkg}->TIEHASH is missing") for
decades (since at least 1996-02-03). This code will now die because my
patch removes the scary Tie​::Hash​::TIEHASH() method that warned and
invoked new() instead.

The same is true for code inheriting for Tie​::Scalar, implementing new()
instead of TIESCALAR().

Tie​::Array does not have a Tie​::Array​::TIEARRAY() method at all, so
inheriting from Tie​::Array without implementing TIEARRAY() never worked.

If your change
breaks older code, it is not suitable for inclusion yet.

Moving the Tie​::StdXxx classes into their own files should not break any
code.

Removing the new() constructor will cause a runtime error in code that
has failed to implement the required TIEHASH() or TIESCALAR()
constructors, ignoring both the warning generated at runtime for decades
and the documentation.

To be compatible even with that code, I would still remove
Tie​::Scalar​::new() and Tie​::Hash​::new(), and replace
Tie​::Scalar​::TIESCALAR() and Tie​:Hash​::TIEHASH() with simpler code that
looks about like this​:

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

On 09/29/2018 07​:26 PM, (via RT) wrote​:

# New Ticket Created by
# Please include the string​: [perl #133551]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=133551 >

This is a bug report for perl from alexander@​foken.de,
generated with the help of perlbug 1.41 running under perl 5.28.0.

Can't inherit from Tie​::StdHash, Tie​::StdArray, Tie​::StdScalar via use
parent. Have to load Tie​::Hash, Tie​::Array, Tie​::Scalar first.
Problem is that the Tie​::Std* classes are hidden in Tie/Hash.pm,
Tie/Array.pm, Tie/Scalar.pm.

use parent 'Tie​::StdHandle' works fine because Tie​::StdHandle is
in Tie/StdHandle.pm, as expected.

My patch moves the Tie​::Std* classes to their own files and removes a
lot of unneeded code.

Test case and patch attached.

Longer description starts at <https://perlmonks.org/?node_id=1221954>

First fully working patch against 5.20.0 at
<https://perlmonks.org/?node_id=1222832;showspoiler=1222832-1>

---
Flags​:
category=library
severity=none
Type=Patch
PatchStatus=HasPatch
module=Tie​::Hash
---
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​:
Platform​:
osname=linux
osvers=4.4.153-foken
archname=x86_64-linux
uname='linux teroknor 4.4.153-foken #2 smp sat sep 15 18​:49​:58 cest
2018 x86_64 intel(r) core(tm)2 duo cpu e8500 @​ 3.16ghz genuineintel
gnulinux '
config_args='-Dmksymlinks -de -Dprefix=/home/alex/perl-source/instdir'
hint=recommended
useposix=true
d_sigaction=define
useithreads=undef
usemultiplicity=undef
use64bitint=define
use64bitall=define
uselongdouble=undef
usemymalloc=n
default_inc_excludes_dot=define
bincompat5005=undef
Compiler​:
cc='cc'
ccflags ='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
optimize='-O2'
cppflags='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include'
ccversion=''
gccversion='5.5.0'
gccosandvers=''
intsize=4
longsize=8
ptrsize=8
doublesize=8
byteorder=12345678
doublekind=3
d_longlong=define
longlongsize=8
d_longdbl=define
longdblsize=16
longdblkind=3
ivtype='long'
ivsize=8
nvtype='double'
nvsize=8
Off_t='off_t'
lseeksize=8
alignbytes=8
prototype=define
Linker and Libraries​:
ld='cc'
ldflags =' -fstack-protector-strong -L/usr/local/lib'
libpth=/usr/local/lib
/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/include-fixed /usr/lib
/lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
libc=libc-2.23.so
so=so
useshrplib=false
libperl=libperl.a
gnulibc_version='2.23'
Dynamic Linking​:
dlsrc=dl_dlopen.xs
dlext=so
d_dlsymun=undef
ccdlflags='-Wl,-E'
cccdlflags='-fPIC'
lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'

---
@​INC for perl 5.28.0​:
/home/alex/perl-source/instdir/lib/site_perl/5.28.0/x86_64-linux
/home/alex/perl-source/instdir/lib/site_perl/5.28.0
/home/alex/perl-source/instdir/lib/5.28.0/x86_64-linux
/home/alex/perl-source/instdir/lib/5.28.0

---
Environment for perl 5.28.0​:
HOME=/home/alex
LANG=en_US
LANGUAGE (unset)
LC_COLLATE=C
LD_LIBRARY_PATH (unset)
LOGDIR (unset)

PATH=/home/alex​:/command​:/usr/local/bin​:/usr/bin​:/bin​:/usr/games​:/usr/lib64/qt/bin​:/usr/share/texmf/bin
PERL_BADLANG (unset)
SHELL=/bin/bash

--
Alexander Foken
mailto​:alexander@​foken.de http​://www.foken.de/alexander/

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

Hi,

here is essentially the same patch again, spread over seven diff files.

01-cleanup-Tie-Array.diff - removes DESTROY(), EXISTS(), DELETE() from
Tie​::Array
02-cleanup-Tie-Hash.diff - adds strict and warnings, removes new(),
TIEHASH(), EXISTS(), changes Hash.t for the new error message
03-cleanup-Tie-Scalar.diff - adds strict and warnings, removes new(),
TIESCALAR(), FETCH(), STORE(), changes Scalar.t for the new error
messages and the lack of new()
04-fix-POD-and-use-parent-in-Tie-StdHandle.diff - fix wrong classname in
Tie​::StdHandle, introduces use parent
05-separate-Tie-StdArray.diff - moves Tie​::StdArray out of Tie/Array.pm,
introduces use parent
06-separate-Tie-StdHash-ExtraHash.diff - moves Tie​:StdHash and
Tie​::ExtraHash out of Tie/Hash.pm, introduces use parent
07-separate-Tie-StdScalar.diff - moves Tie​::StdScalar out of
Tie/Scalar.pm, introduces use parent

Applied in order, all patches apply cleanly on 5.28.0, no tests fail
after each of the patches.

The three *-cleanup-* patches 01, 02, and 03 ...
- remove new(), which can't be used for tie on its own
- remove TIEHASH() and TIESCALAR() which only cause runtime errors
unless new() or TIEHASH() resp. TIESCALAR() exists in an inheriting class
- remove EXISTS(), DELETE(), FETCH(), STORE(), which cause unconditioal
runtime errors
- remove empty DESTROY(), already implemented in UNIVERSAL
- change tests to test for perl's default error messages instead of the
ones generated by the removed code

Overall, these three patches change the error messages generated by
broken code.
They also require inheriting classes to use the proper constructor names
(TIEHASH, TIESCALAR) instead of new, which caused a runtime warning for
years, if not decades.

This should not break any code that did not warn before. It may break
tests that insist on a specific error message.

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
Tie​::ExtraHash classes out of the base classes and switch to use parent
instead of manipulating @​ISA.

Again, this should have no visible difference except for parent and a
few more files (containing Tie​::Std* and Tie​::ExtraHash) being loaded.
All base classes automatically the classes previously embedded in the
package.

use parent 'Tie​::StdHash', use parent 'Tie​::StdArray', use parent
'Tie​::StdScalar', use parent 'Tie​::ExtraHash' now just work.

Regards,
Alexander

On 05.10.2018 16​:16, Sawyer X via RT wrote​:

Thank you for the patch!

It's a bit harder to review because you include different types of
changes (renaming, clean ups) but made it into a single patch. Having
multiple patches for each change (even if it's only "0001-rename.patch"
and "0002-cleanups.patch") with explanations of what's being done would
make it much easier for us to quickly review this.

Could you specify what the behavior would be for those that still load
Tie​::{Scalar,Array,Hash} to receive the :​:Std version? If your change
breaks older code, it is not suitable for inclusion yet.

On 09/29/2018 07​:26 PM, (via RT) wrote​:

# New Ticket Created by
# Please include the string​: [perl #133551]
# in the subject line of all future correspondence about this issue.
# <URL​:https://rt-archive.perl.org/perl5/Ticket/Display.html?id=133551  >

This is a bug report for perl fromalexander@​foken.de,
generated with the help of perlbug 1.41 running under perl 5.28.0.

Can't inherit from Tie​::StdHash, Tie​::StdArray, Tie​::StdScalar via use
parent. Have to load Tie​::Hash, Tie​::Array, Tie​::Scalar first.
Problem is that the Tie​::Std* classes are hidden in Tie/Hash.pm,
Tie/Array.pm, Tie/Scalar.pm.

use parent 'Tie​::StdHandle' works fine because Tie​::StdHandle is
in Tie/StdHandle.pm, as expected.

My patch moves the Tie​::Std* classes to their own files and removes a
lot of unneeded code.

Test case and patch attached.

Longer description starts at<https://perlmonks.org/?node_id=1221954>

First fully working patch against 5.20.0 at
<https://perlmonks.org/?node_id=1222832;showspoiler=1222832-1>

---
Flags​:
category=library
severity=none
Type=Patch
PatchStatus=HasPatch
module=Tie​::Hash
---
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​:
Platform​:
osname=linux
osvers=4.4.153-foken
archname=x86_64-linux
uname='linux teroknor 4.4.153-foken #2 smp sat sep 15 18​:49​:58 cest
2018 x86_64 intel(r) core(tm)2 duo cpu e8500 @​ 3.16ghz genuineintel
gnulinux '
config_args='-Dmksymlinks -de -Dprefix=/home/alex/perl-source/instdir'
hint=recommended
useposix=true
d_sigaction=define
useithreads=undef
usemultiplicity=undef
use64bitint=define
use64bitall=define
uselongdouble=undef
usemymalloc=n
default_inc_excludes_dot=define
bincompat5005=undef
Compiler​:
cc='cc'
ccflags ='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
optimize='-O2'
cppflags='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include'
ccversion=''
gccversion='5.5.0'
gccosandvers=''
intsize=4
longsize=8
ptrsize=8
doublesize=8
byteorder=12345678
doublekind=3
d_longlong=define
longlongsize=8
d_longdbl=define
longdblsize=16
longdblkind=3
ivtype='long'
ivsize=8
nvtype='double'
nvsize=8
Off_t='off_t'
lseeksize=8
alignbytes=8
prototype=define
Linker and Libraries​:
ld='cc'
ldflags =' -fstack-protector-strong -L/usr/local/lib'
libpth=/usr/local/lib
/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/include-fixed /usr/lib
/lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
libc=libc-2.23.so
so=so
useshrplib=false
libperl=libperl.a
gnulibc_version='2.23'
Dynamic Linking​:
dlsrc=dl_dlopen.xs
dlext=so
d_dlsymun=undef
ccdlflags='-Wl,-E'
cccdlflags='-fPIC'
lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'

---
@​INC for perl 5.28.0​:
/home/alex/perl-source/instdir/lib/site_perl/5.28.0/x86_64-linux
/home/alex/perl-source/instdir/lib/site_perl/5.28.0
/home/alex/perl-source/instdir/lib/5.28.0/x86_64-linux
/home/alex/perl-source/instdir/lib/5.28.0

---
Environment for perl 5.28.0​:
HOME=/home/alex
LANG=en_US
LANGUAGE (unset)
LC_COLLATE=C
LD_LIBRARY_PATH (unset)
LOGDIR (unset)

PATH=/home/alex​:/command​:/usr/local/bin​:/usr/bin​:/bin​:/usr/games​:/usr/lib64/qt/bin​:/usr/share/texmf/bin
PERL_BADLANG (unset)
SHELL=/bin/bash

--
Alexander Foken
mailto​:alexander@​foken.de http​://www.foken.de/alexander/

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

01-cleanup-Tie-Array.diff
diff -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

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

02-cleanup-Tie-Hash.diff
diff -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()" );
 }

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

03-cleanup-Tie-Scalar.diff
diff -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";

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

04-fix-POD-and-use-parent-in-Tie-StdHandle.diff
diff -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

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

05-separate-Tie-StdArray.diff
diff -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

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

06-separate-Tie-StdHash-ExtraHash.diff
diff -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;

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2018

From alexander@foken.de

07-separate-Tie-StdScalar.diff
diff -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
+
+

@jkeenan
Copy link
Contributor

jkeenan commented Jul 10, 2022

"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.

@jkeenan jkeenan self-assigned this Jul 10, 2022
@jkeenan jkeenan added the Closable? We might be able to close this ticket, but we need to check with the reporter label Jul 10, 2022
@haarg
Copy link
Contributor

haarg commented Jul 11, 2022

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.

@jkeenan jkeenan removed their assignment Jul 11, 2022
@jkeenan jkeenan removed the Closable? We might be able to close this ticket, but we need to check with the reporter label Jul 11, 2022
@haarg haarg self-assigned this Jul 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants