develooper Front page | perl.perl5.porters | Postings from January 2004

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

Thread Next
January 18, 2004 17:18
[perl #24942] fields::inherit doesn't bless derived package's \%FIELDS, results in phash deprecation errors.
Message ID:
# New Ticket Created by 
# Please include the string:  [perl #24942]
# in the subject line of all future correspondence about this issue. 
# <URL: >

This is a bug report for perl from,
generated with the help of perlbug 1.34 running under perl v5.8.1.

[Please enter your report here]

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


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.


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, which now handles fields::inherit, and the
test suite. It is against the 5.8.3 tree.

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/ perl-5.8.3-inherit-has-no-fields-phash-warning/lib/
--- perl-5.8.3/lib/	Fri Dec 19 10:13:27 2003
+++ perl-5.8.3-inherit-has-no-fields-phash-warning/lib/	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 {

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

	package B8

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

	package main;


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

[Please do not change anything below this line]
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:
    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
    cc='cc', ccflags ='-g -pipe -pipe -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -I/usr/local/include',
    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
  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:

@INC for perl v5.8.1:

Environment for perl v5.8.1:
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PERL_BADLANG (unset)

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About