I’m trying to understand the behavior of the fields pragma, which I find poorly documented, regarding fields prefixed with underscores. This is what the documentation has to say about it:
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 not consistent with its actual behavior, according to my test, below. Not only are _-prefixed fields visible within a subclass, they are visible within foreign classes as well (unless I don’t get what ‘visible’ means). Also, directly accessing the restricted hash works fine.
Where can I find more about the behavior of the fields pragma, short of going at the source code?
{
package Foo;
use strict;
use warnings;
use fields qw/a _b __c/;
sub new {
my ( $class ) = @_;
my Foo $self = fields::new($class);
$self->a = 1; $self->b = 2; $self->c = 3;
return $self;
}
sub a : lvalue { shift->{a} }
sub b : lvalue { shift->{_b} }
sub c : lvalue { shift->{__c} }
}
{
package Bar;
use base 'Foo';
use strict;
use warnings;
use Data::Dumper;
my $o = Bar->new;
print Dumper $o; ##$VAR1 = bless({'_b' => 2, '__c' => 3, 'a' => 1}, 'Foo');
$o->a = 4; $o->b = 5; $o->c = 6;
print Dumper $o; ##$VAR1 = bless({'_b' => 5, '__c' => 6, 'a' => 4}, 'Foo');
$o->{a} = 7; $o->{_b} = 8; $o->{__c} = 9;
print Dumper $o; ##$VAR1 = bless({'_b' => 8, '__c' => 9, 'a' => 7}, 'Foo');
}
Coincidentally enough, I happen to have a test script in
~/codescraps/fields/test.pldated from two years ago when I experimented with answering exactly this same question. 🙂And when I run your code, I get the error:
(line 16 is the definition for sub b.) What architecture are you running this on? Objects using the fields pragma aren’t simple blessed hashrefs — they are blessed arrayrefs, e.g. when I modify your constructor to look like this:
I see:
As a postscript, I feel obliged to point out that the fields pragma, and the base pragma that goes with it, are both deprecated and one is strongly urged to avoid using them. Nowadays, if you’re looking to construct a nice OO module with accessors, one would either use Class::Accessor or go directly to Moose.