Поля
СОДЕРЖАНИЕ
ИМЯ
fields - поля класса на этапе компиляции
СИНТАКСИС
{
package Foo;
use fields qw(foo bar _Foo_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 $var = Foo->new;
$var->{foo} = 42;
# this will generate a run-time error
$var->{zap} = 42;
# this will generate a compile-time error
my Foo $foo = Foo->new;
$foo->{zap} = 24;
# subclassing
{
package Bar;
use base 'Foo';
use fields qw(baz _Bar_private); # 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;
}
} ОПИСАНИЕ
Директива fields позволяет проверять поля класса на этапе компиляции и выполнения.
ПРИМЕЧАНИЕ: В текущей реализации объявленные поля хранятся в хеше %FIELDS вызывающего пакета, но это может измениться в будущих версиях. Не обновляйте хеш %FIELDS напрямую, так как он должен создаваться на этапе компиляции, чтобы быть полностью полезным, как это делается с помощью этой директивы.
Если используется типизированная лексическая переменная (my Class $var) содержащая ссылку для доступа к элементу хеша, и пакет с таким же именем, как тип, объявил поля класса с использованием этой директивы, то ключ хеша проверяется на этапе компиляции. Если переменные не типизированы, доступ проверяется только во время выполнения.
Связанная директива base объединит поля из базовых классов и любые поля, объявленные с использованием директивы fields. Это позволяет правильно работать с наследованием полей. Наследуемые поля могут быть переопределены, но если включены предупреждения, будет выведено предупреждение.
Только для Perl 5.8.x и более ранних версий: Имена полей, начинающиеся с символа подчеркивания, являются приватными для класса и не видны подклассам.
Также, в Perl 5.8.x и более ранних версиях, эта директива использует псевдо-хеши, что позволяет создавать объекты с именованными полями, которые так же компактны и быстры для доступа, как массивы, пока объекты обращаются через должным образом типизированные переменные.
Поддерживаются следующие функции:
- new
-
fields::new() создаёт и благословляет хеш, состоящий из полей, объявленных с использованием директивы
fieldsв указанном классе. Это рекомендуемый способ создания объекта, основанного на полях.Это позволяет написать конструктор, например, так:
package Critter::Sounds; use fields qw(cat dog bird); sub new { my $self = shift; $self = fields::new($self) unless ref $self; $self->{cat} = 'meow'; # scalar element @$self{'dog','bird'} = ('bark','tweet'); # slice return $self; } - phash
-
Эта функция работает только в Perl 5.8.x и более ранних версиях. Псевдо-хеши были удалены из Perl с версии 5.10. Рассмотрите использование ограниченных хешей или fields::new() вместо них (в версии 5.10+ оно использует ограниченные хеши). Смотрите Hash::Util. Использование fields::phash() в 5.10 или более поздних версиях вызовет ошибку.
fields::phash() может использоваться для создания и инициализации обычного (неблагословлённого) псевдо-хеша. Эта функция всегда должна использоваться вместо непосредственного создания псевдо-хешей.
Если первый аргумент - ссылка на массив, псевдо-хеш будет создан с ключами из этого массива. Если указан второй аргумент, он также должен быть ссылкой на массив, элементы которого будут использоваться в качестве значений. Если второй массив содержит меньше элементов, чем первый, хвостовые элементы псевдо-хеша не будут инициализированы. Это особенно полезно для создания псевдо-хеша из аргументов подпрограммы:
sub dogtag { my $tag = fields::phash([qw(name rank ser_num)], [@_]); }fields::phash() также принимает список пар ключ-значение, которые будут использоваться для создания псевдо-хеша. Примеры:
my $tag = fields::phash(name => "Joe", rank => "captain", ser_num => 42); my $pseudohash = fields::phash(%args);
СМОТРИТЕ ТАКЖЕ
© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/fields