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
pragma 啟用編譯時間和執行時間驗證的類別欄位。
注意:目前的實作會將宣告的欄位保存在呼叫套件的 %FIELDS hash 中,但這可能會在未來的版本中變更。請勿直接更新 %FIELDS hash,因為它必須在編譯時間建立才能完全發揮作用,就像這個 pragma 所做的一樣。
如果使用包含參考的型態化詞法變數 (my Class $var
) 來存取 hash 元素,且與型態名稱相同的套件已使用這個 pragma 宣告類別欄位,那麼 hash 鍵會在編譯時間驗證。如果變數未型態化,則只會在執行時間檢查存取。
相關的 base
pragma 會結合基底類別的欄位和使用 fields
pragma 宣告的任何欄位。這能讓欄位繼承正常運作。繼承的欄位可以被覆寫,但如果啟用警告,則會產生警告。
僅適用於 Perl 5.8.x 及更早版本:以底線字元開頭的欄位名稱會對類別保密,且對子類別不可見。
另外,在 Perl 5.8.x 及更早版本中,這個 pragma 使用偽 hash,其效果是您可以擁有具有命名欄位的物件,這些物件與緊湊且快速存取的陣列一樣,只要物件是透過正確型態化的變數存取。
支援下列函式
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;
}
此函式僅在 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);