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

fields::inherit doesn't bless derived package's \%FIELDS, results in phash deprecation errors. #7044

Closed
p5pRT opened this issue Jan 18, 2004 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 18, 2004

Migrated from rt.perl.org#24942 (status was 'resolved')

Searchable as RT24942$

@p5pRT
Copy link
Author

p5pRT commented Jan 18, 2004

From @nothingmuch

Created by @nothingmuch

Though reported under 5.8.1, this bug was tested for in 5.8.3. I
promise ;-).

When using the fields pragma, in something like

<<EOF;

package Foo;

use fields qw/foo/;

sub new {
  my $pkg = shift;
  my $self = $pkg->fields​::new();
 
  $self->{foo} = 'ding';
}

package Bar;

use base qw/Foo/;

package main;

new Foo; # will not generate an error
new Bar; # will generate an error.

EOF

In 5.8.1 the blessing of \%FIELDS into the 'pseudohash' class was
introduced, to suppress errors.

&fields​::inherit doesn't bless that referant though, so errors for a
derived class are not suppressed.

A solution could be to do

  my $derived_fields = \%{"$derived\​::FIELDS"};
  bless $derived_fields, 'pseudohash';

which resolves the issue.

  if (ref $derived_fields !~ /^pseudohash/){
  bless $derived_fields, 'pseudohash';
  }

can also be done, to supress reblessing (why?).

This should be wrapped in

  if ($] < 5.0009){

  }

as 5.9 changes %FIELDS to be a has locked with &Hash​::Utils​::lock_keys.

Here is a patch to base.pm, which now handles fields​::inherit, and the
test suite. It is against the 5.8.3 tree.

EOF

Inline Patch
diff -ru perl-5.8.3/lib/base/t/fields-base.t perl-5.8.3-inherit-has-no-fields-phash-warning/lib/base/t/fields-base.t
--- perl-5.8.3/lib/base/t/fields-base.t	Tue Sep 16 08:28:46 2003
+++ perl-5.8.3-inherit-has-no-fields-phash-warning/lib/base/t/fields-base.t	Sun Jan 18 16:47:02 2004
@@ -20,7 +20,7 @@
 }
 
 use strict;
-use Test::More tests => 25;
+use Test::More tests => 26;
 
 BEGIN { use_ok('base'); }
 
@@ -194,3 +194,23 @@
 ::like( $@, qr/Can't multiply inherit %FIELDS/i, 'Again, no multi inherit' );
 
 
+# Test that a package with no fields can inherit from a package with fields, and that pseudohash messages don't show up
+package B9;
+use fields qw(b1);
+
+sub _mk_obj { fields::new($_[0])->{'b1'} };
+
+package D9;
+use base qw(B9);
+
+package main;
+
+{
+	my $w = 0;
+	local $SIG{__WARN__} = sub { $w++ };
+	
+	B9->_mk_obj();
+	D9->_mk_obj(); # used tp emit a warning that pseudohashes are deprecated, because %FIELDS wasn't blessed.
+	
+	is ($w, 0, "pseudohash warnings in derived class with no fields of it's own");	
+}
diff -ru perl-5.8.3/lib/base.pm perl-5.8.3-inherit-has-no-fields-phash-warning/lib/base.pm
--- perl-5.8.3/lib/base.pm	Fri Dec 19 10:13:27 2003
+++ perl-5.8.3-inherit-has-no-fields-phash-warning/lib/base.pm	Sun Jan 18 16:10:31 2004
@@ -42,7 +42,11 @@
     # Shut up a possible typo warning.
     () = \%{$_[0].'::FIELDS'};
 
-    return \%{$_[0].'::FIELDS'};
+    my $f = \%{$_[0].'::FIELDS'};
+
+    bless $f, 'pseudohash' if ($] < 5.009 and ref($f) ne 'pseudohash'); # should be centrallized in fields? perhaps fields::mk_FIELDS_be_OK. Peh. As long as %{ $package . '::FIELDS' } is used here anyway, it doesn't matter.
+
+    return $f;
 }
 
 sub import {
EOF

The test classes could also be B8 and D8, with only

  package B8

  sub _mk_obj { $_[0]->fields​::new()->{'_b1'} };

  package main;

  B8->_mk_obj();
  D8->_mk_obj();

but the naming scheme was not so coherent to me. Plus, being hermetic
is more important than being efficient, in test suites.

Perl Info

Flags:
    category=library
    severity=medium

Site configuration information for perl v5.8.1:

Configured by root at Fri Sep 12 19:46:46 PDT 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 1 RC3) configuration:
  Platform:
    osname=darwin, osvers=7.0, archname=darwin-thread-multi-2level
    uname='darwin hampsten 7.0 darwin kernel version 6.0: fri jul 25 16:58:41 pdt 2003; root:xnu-344.frankd.rootsxnu-344.frankd~objrelease_ppc power macintosh powerpc '
    config_args='-ds -e -Dprefix=/usr -Dccflags=-g  -pipe  -Dldflags=-Dman3ext=3pm -Duseithreads -Duseshrplib'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-g -pipe -pipe -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -I/usr/local/include',
    optimize='-Os',
    cppflags='-no-cpp-precomp -g -pipe -pipe -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='3.3 20030304 (Apple Computer, Inc. build 1495)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags ='-L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib
    libs=-ldbm -ldl -lm -lc
    perllibs=-ldl -lm -lc
    libc=/usr/lib/libc.dylib, so=dylib, useshrplib=true, libperl=libperl.dylib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dyld.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-bundle -undefined dynamic_lookup -L/usr/local/lib'

Locally applied patches:
    RC3


@INC for perl v5.8.1:
    /System/Library/Perl/5.8.1/darwin-thread-multi-2level
    /System/Library/Perl/5.8.1
    /Library/Perl/5.8.1/darwin-thread-multi-2level
    /Library/Perl/5.8.1
    /Library/Perl
    /Network/Library/Perl/5.8.1/darwin-thread-multi-2level
    /Network/Library/Perl/5.8.1
    /Network/Library/Perl
    .


Environment for perl v5.8.1:
    DYLD_LIBRARY_PATH (unset)
    HOME=/Users/nothingmuch
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin/:/usr/local/bin:/usr/local/teTeX/bin/powerpc-apple-darwin-current
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2004

From @iabyn

On Sun, Jan 18, 2004 at 03​:15​:46PM -0000, nothingmuch@​woobling.org (via RT) wrote​:

When using the fields pragma, in something like

<<EOF;

package Foo;

use fields qw/foo/;

sub new {
my $pkg = shift;
my $self = $pkg->fields​::new();

$self\->\{foo\} = 'ding';

}

package Bar;

use base qw/Foo/;

package main;

new Foo; # will not generate an error
new Bar; # will generate an error.

EOF
[snip]
Here is a patch to base.pm, which now handles fields​::inherit, and the
test suite. It is against the 5.8.3 tree.

Thanks, applied to bleedperl as change #22208. I took the liberty in your
patched code of wrapping lines > 80 chars and changing the indentation
form 8 to 4 to match the surrounding code. I also turned $] < 5.009
from a run-time to compile-time test.

Dave.

--
"You're so sadly neglected, and often ignored.
A poor second to Belgium, When going abroad."
  -- Monty Python - "Finland"

Change 22208 by davem@​davem-percy on 2004/01/24 16​:13​:17

  Subject​: [perl #24942] fields​::inherit doesn't bless derived
  package's \%FIELDS, results in phash deprecation errors.
  From​: "nothingmuch@​woobling.org (via RT)" <perlbug-followup@​perl.org>
  Date​: 18 Jan 2004 15​:15​:46 -0000
  Message-Id​: <rt-3.0.8-24942-70144.16.7177902690315@​perl.org>

Affected files ...

... //depot/perl/lib/base.pm#26 edit
... //depot/perl/lib/base/t/fields-base.t#2 edit

Differences ...

==== //depot/perl/lib/base.pm#26 (text) ====

@​@​ -38,11 +38,26 @​@​
  return $Fattr->{$_[0]};
}

-sub get_fields {
- # Shut up a possible typo warning.
- () = \%{$_[0].'​::FIELDS'};
+if ($] < 5.009) {
+ *get_fields = sub {
+ # Shut up a possible typo warning.
+ () = \%{$_[0].'​::FIELDS'};
+ my $f = \%{$_[0].'​::FIELDS'};
+
+ # should be centralized in fields? perhaps
+ # fields​::mk_FIELDS_be_OK. Peh. As long as %{ $package . '​::FIELDS' }
+ # is used here anyway, it doesn't matter.
+ bless $f, 'pseudohash' if (ref($f) ne 'pseudohash');

- return \%{$_[0].'​::FIELDS'};
+ return $f;
+ }
+}
+else {
+ *get_fields = sub {
+ # Shut up a possible typo warning.
+ () = \%{$_[0].'​::FIELDS'};
+ return \%{$_[0].'​::FIELDS'};
+ }
}

sub import {

==== //depot/perl/lib/base/t/fields-base.t#2 (text) ====

@​@​ -20,7 +20,7 @​@​
}

use strict;
-use Test​::More tests => 25;
+use Test​::More tests => 26;

BEGIN { use_ok('base'); }

@​@​ -194,3 +194,27 @​@​
:​:like( $@​, qr/Can't multiply inherit %FIELDS/i, 'Again, no multi inherit' );

+# Test that a package with no fields can inherit from a package with
+# fields, and that pseudohash messages don't show up
+
+package B9;
+use fields qw(b1);
+
+sub _mk_obj { fields​::new($_[0])->{'b1'} };
+
+package D9;
+use base qw(B9);
+
+package main;
+
+{
+ my $w = 0;
+ local $SIG{__WARN__} = sub { $w++ };
+
+ B9->_mk_obj();
+ # used tp emit a warning that pseudohashes are deprecated, because
+ # %FIELDS wasn't blessed.
+ D9->_mk_obj();
+
+ is ($w, 0, "pseudohash warnings in derived class with no fields of it's own");
+}

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2004

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

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2004

@iabyn - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant