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
From:
perlbug-followup
Date:
January 18, 2004 17:18
Subject:
[perl #24942] fields::inherit doesn't bless derived package's \%FIELDS, results in phash deprecation errors.
Message ID:
rt-3.0.8-24942-70144.16.7177902690315@perl.org
# New Ticket Created by  nothingmuch@woobling.org 
# Please include the string:  [perl #24942]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=24942 >


This is a bug report for perl from nothingmuch@woobling.org,
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


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

[Please do not change anything below this line]
-----------------------------------------------------------------
---
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

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About