Если вы работаете в Perl 5.10 и выше (на самом деле 5.9 и выше, но я не считаю выпуски разработки), fields
создает ограниченный хеш. См. Hash :: Util для получения информации об ограниченных хэшах.
Чтобы получить все поля, доступные для ограниченного хэша, используйте функции legal_keys
или legal_ref_keys
:
use Hash::Util qw( legal_ref_keys );
my $froot = Fruit->new();
my @attribs = legal_ref_keys($froot);
Вы можете сделать несколько вещей, чтобы генерировать свои методы автоматически:
- Создайте временный объект во время создания и запросите у него юридические ключи, чтобы вы могли создавать атрибуты --- UGLY
- AUTOLOAD атрибутов путем запроса объекта для списка легальных ключей. ПРЕДУПРЕЖДЕНИЕ О КОДЕКСОМ: это предполагает, что все подклассы будут использовать одну и ту же базовую структуру данных.
- Доступ к хешу
%FIELDS
в модуле для генерации методов во время компиляции или через AUTOLOAD. БОЛЬШЕ ПРОБЛЕМ - предполагается, что неопубликованный бит прагмы fields
останется.
- Определение массива атрибутов во время компиляции и автоматическое создание методов, а также установка полей на основе значения.
- Перестань писать все эти шаблоны и используй лося.
Вариант 4:
package Fruit;
use strict;
use warnings;
my @ATTRIBUTES;
BEGIN { @ATTRIBUTES = qw( color shape taste ); }
use fields @ATTRIBUTES;
for my $attrib ( @ATTRIBUTES ) {
my $getset = sub {
my $self = shift;
if( @_ ) {
$self->{$attrib} = shift;
}
return $self->{$attrib};
};
{ no strict 'refs';
*{$attrib} = $getset;
}
}
sub new {
my ( $class, $params ) = @_;
my $self = fields::new( $class ) unless ref $class;
foreach my $name ( keys %$params ) {
$self->{ $name } = $params->{ $name };
}
return $self;
}
Вариант 5.
package Fruit;
use Moose;
has 'color' => (
is => 'rw',
isa => 'Str',
);
has 'shape' => (
is => 'rw',
isa => 'Str',
);
has 'taste' => (
is => 'rw',
isa => 'Str',
);