По совпадению, у меня есть тестовый скрипт в ~/codescraps/fields/test.pl
, датированный два года назад, когда я экспериментировал с ответом точно на этот же вопрос. :)
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
{
package Foo;
use fields qw(foo bar _Foo_private);
use private qw(_really_private);
sub new {
my Foo $self = shift;
unless (ref $self) {
$self = fields::new($self);
$self->{_Foo_private} = "this is Foo's secret";
}
$self->{foo} = 10;
$self->{bar} = 20;
return $self;
}
}
my $foo = Foo->new;
$foo->{foo} = 42;
# this will generate an error: field does not exist
#$foo->{zap} = 42;
print "_Foo_private: " . $foo->{_Foo_private} . "\n";
$foo->{_Foo_private} = 1;
print "_Foo_private: " . $foo->{_Foo_private} . "\n";
print "_really_private: " . $foo->{_really_private} . "\n";
$foo->{_really_private} = 1;
print "_really_private: " . $foo->{_really_private} . "\n";
print Dumper($foo);
# subclassing
{
package Bar;
use base 'Foo';
use fields qw(baz _Bar_private); # these fields not shared with Foo
sub new {
my $class = shift;
my $self = fields::new($class);
$self->SUPER::new(); # init base fields
$self->{baz} = 10; # init own fields
$self->{_Bar_private} = "this is Bar's secret";
return $self;
}
}
my $bar = Bar->new;
# these work fine
$bar->{foo} = 1;
$bar->{bar} = 1;
$bar->{_Bar_private} = 1;
# this will not work - underscored fields are not visible to children
$bar->{_Foo_private} = 1;
И когда я запускаю ваш код, я получаю сообщение об ошибке:
No such pseudo-hash field "_b" at test2.pl line 16.
(строка 16 - это определение для подпункта b.) На какой архитектуре вы это используете? Объекты, использующие прагму полей, не являются простыми благословенными хеш-ссылками - они являются благословенными массивами, например, когда я изменяю ваш конструктор, чтобы он выглядел так:
sub new {
my ( $class ) = @_;
my Foo $self = fields::new($class);
$self->{a} = 1; $self->{_b} = 2; $self->{__c} = 3;
print "I look like: ", Data::Dumper::Dumper($self);
return $self;
}
Понятно:
I look like: $VAR1 = bless( [
bless( {
'a' => 1
}, 'pseudohash' ),
1,
2,
3
], 'Bar' );
Как постскриптум, я чувствую себя обязанным указать, что прагма полей и прагма base , которые с ней связаны, устарели, и настоятельно рекомендуется избегать использования их. В настоящее время, если вы хотите создать хороший модуль OO с аксессорами, можно использовать Class :: Accessor или перейти непосредственно к Moose .