An issue in perl 5.10

From fields:

Field names that start with an underscore character are made private to the class and are not visible to subclasses. Inherited fields can be overridden but will generate a warning if used together with the "-w" switch.

This is however only the case for perl 5.8. Consider the following code (in separate files as base borks if they are in the same script):

Base.pm:
package Base; use strict; use warnings; use fields qw( _f ); sub new { my Base $self = shift; if ( !ref $self ) { $self = fields::new( $self ); } $self->{_f} = 'base'; return $self; } sub base { my Base $self = shift; $self->{_f}; } sub set_base { my Base $self = shift; $self->{_f} = shift; } 1;
Derived.pm:
package Derived; use strict; use warnings; use base 'Base'; use fields qw( _f ); sub new { my $class = shift; my Derived $self = fields::new( $class ); $self->SUPER::new(); $self->{_f} = 'derived'; return $self; } sub derived { my Derived $self = shift; $self->{_f}; } 1;
Test script:
#!/usr/bin/perl use strict; use warnings; use Test::More tests => 4; use Derived; my Derived $obj = Derived->new(); is( $obj->base(), 'base', 'Base::_f eq base' ); is( $obj->derived(), 'derived', 'Derived::_f eq derived' ); diag( 'Setting Base::_f to base2' ); $obj->set_base( 'base2' ); is( $obj->base(), 'base2', 'Base::_f eq base2' ); is( $obj->derived(), 'derived', 'Derived::_f still eq derived' ); 1;

These tests pass on Perl 5.8.8, most likely because of the pseudo-hash implementation. However, on Perl 5.10 _f is shared between Base and Derived, and base() always returns the same as derived().

What's more, the documented warning is emitted only for public fields, so Perl stays silent here, while it would croak had I named my field f. This sounds like a bug, I'll try to report it when I have some free time.

In the end, I think that fields are still usable, but unless (until?) this issue gets resolved, private fields are best implemented as

sub PKG() { __PACKAGE__ } ... $self->{PKG.'.foo'} = 42;
(that's the shortest/least ugly syntax that the compiler seems able to compile-time check).


In reply to Re: Fields pragma - the poor man's OO framework? by waba
in thread Fields pragma - the poor man's OO framework? by waba

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.