内容

名称

字段 - 编译时类字段

概要

{
    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 及更早版本中,此 pragma 使用伪哈希,其效果是您可以拥有具有命名字段的对象,这些对象与数组一样紧凑且快速访问,只要通过正确类型的变量访问这些对象即可。

支持以下函数

new

fields::new() 创建并祝福一个哈希,该哈希包含使用 fields pragma 在指定类中声明的字段。这是构建基于字段的对象的推荐方法。

这使得编写这样的构造函数成为可能

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。在 5.10 或更高版本下使用 fields::phash() 会导致错误。

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);

另请参见

base, Hash::Util