Test2::Util::HashBase - 建立基於雜湊的類別。
一個類別
package My::Class;
use strict;
use warnings;
# Generate 3 accessors
use Test2::Util::HashBase qw/foo -bar ^baz <bat >ban +boo/;
# Chance to initialize defaults
sub init {
my $self = shift; # No other args
$self->{+FOO} ||= "foo";
$self->{+BAR} ||= "bar";
$self->{+BAZ} ||= "baz";
$self->{+BAT} ||= "bat";
$self->{+BAN} ||= "ban";
$self->{+BOO} ||= "boo";
}
sub print {
print join ", " => map { $self->{$_} } FOO, BAR, BAZ, BAT, BAN, BOO;
}
建立子類別
package My::Subclass;
use strict;
use warnings;
# Note, you should subclass before loading HashBase.
use base 'My::Class';
use Test2::Util::HashBase qw/bub/;
sub init {
my $self = shift;
# We get the constants from the base class for free.
$self->{+FOO} ||= 'SubFoo';
$self->{+BUB} ||= 'bub';
$self->SUPER::init();
}
使用它
package main;
use strict;
use warnings;
use My::Class;
# These are all functionally identical
my $one = My::Class->new(foo => 'MyFoo', bar => 'MyBar');
my $two = My::Class->new({foo => 'MyFoo', bar => 'MyBar'});
my $three = My::Class->new(['MyFoo', 'MyBar']);
# Readers!
my $foo = $one->foo; # 'MyFoo'
my $bar = $one->bar; # 'MyBar'
my $baz = $one->baz; # Defaulted to: 'baz'
my $bat = $one->bat; # Defaulted to: 'bat'
# '>ban' means setter only, no reader
# '+boo' means no setter or reader, just the BOO constant
# Setters!
$one->set_foo('A Foo');
#'-bar' means read-only, so the setter will throw an exception (but is defined).
$one->set_bar('A bar');
# '^baz' means deprecated setter, this will warn about the setter being
# deprecated.
$one->set_baz('A Baz');
# '<bat' means no setter defined at all
# '+boo' means no setter or reader, just the BOO constant
$one->{+FOO} = 'xxx';
此套件用於根據雜湊參考建立類別。使用此類別將提供 new()
方法,以及產生您要求的存取器。產生的存取器將是 getter,也會為您產生 set_ACCESSOR
setter。您還可為每個存取器取得常數(全大寫),這些常數會傳回該存取器的雜湊鍵。也支援單一繼承。
這是 Object::HashBase 的套件版本。此檔案是使用 /home/exodist/perl5/perlbrew/perls/main/bin/hashbase_inc.pl
這個指令碼產生的。
建立新的執行個體。
如果您的套件繼承鏈中已經有 new()
方法,HashBase 將不會匯出 new()
。
如果您不想要這個方法,您可以定義自己的方法,只要在載入 Test2::Util::HashBase 之前宣告即可。
package My::Package;
# predeclare new() so that HashBase does not give us one.
sub new;
use Test2::Util::HashBase qw/foo bar baz/;
# Now we define our own new method.
sub new { ... }
這樣 HashBase 就能看到您有自己的 new()
方法。或者,您可以在載入 HashBase 之前定義方法,而不用宣告,但這樣會分散您的使用陳述式。
建立物件最常見的方式是傳入鍵值對,其中每個鍵都是屬性,每個值都是您要指定給該屬性的值。不會進行任何檢查以驗證屬性或值是否有效,您可以在 init()
中執行此操作(如果需要)。
如果您願意,您可以傳入 hashref,而不是成對。當您這樣做時,將會複製 hashref,而複製品將會被標記為物件傳回。無法要求 HashBase 標記特定的 hashref。
在某些情況下,物件可能只有一個或兩個屬性,在這種情況下,hashref 對您來說可能太過冗長。在這些情況下,您可以傳入只包含值的陣列參考。這些值將會按照屬性列出的順序指定給屬性。當涉及繼承時,父類別的屬性將出現在子類別之前。
這讓您有機會為欄位設定一些預設值。唯一的引數是 $self
,其索引已經從建構函式設定。
注意: Test2::Util::HashBase 會在建構期間使用 $class->can('init')
檢查 init。它不會對建立的物件呼叫 can()
。另請注意,檢查結果會快取,只會檢查一次,也就是在建立類別執行個體時。這表示在第一次建構後新增 init()
方法將會導致它被忽略。
要產生存取器,請在使用模組時列出它們
use Test2::Util::HashBase qw/foo/;
這將在您的命名空間中產生下列子程式
Getter,用於取得 foo
欄位的數值。
Setter,用於設定 foo
欄位的數值。
常數,傳回欄位 foo
在類別 hashref 中的鍵。子類別也會取得此函式作為常數,而並非僅僅是方法,表示它已複製到子類別名稱空間中。
使用這些常數的主要原因是協助避免拼寫錯誤和類似錯別字。不過,如果你忘記加上 '+' 前綴,它將無法提供協助。
use Test2::Util::HashBase qw/-foo/;
擲回例外狀況,告知你屬性為唯讀。這會匯出以覆寫父類別中屬性的任何作用中 setter。
use Test2::Util::HashBase qw/^foo/;
這將設定數值,但也會警告你該方法已棄用。
use Test2::Util::HashBase qw/<foo/;
僅提供讀取器,完全未定義 set_foo
方法。
use Test2::Util::HashBase qw/>foo/;
僅提供寫入 (set_foo
),完全未定義 foo
方法。
use Test2::Util::HashBase qw/+foo/;
這不會為你建立任何方法,它僅新增 FOO
常數。
你可以對現有的 HashBase 類別進行子類別化。
use base 'Another::HashBase::Class';
use Test2::Util::HashBase qw/foo bar baz/;
基本類別會新增到 @ISA
中,而基本類別中的所有常數會自動新增到子類別中。
Test2::Util::HashBase 提供一個函式,用於擷取 Test2::Util::HashBase 類別的屬性清單。
上述任一格式皆可使用。這將傳回物件上定義的屬性清單。此清單會以屬性定義順序傳回,父類別屬性會列在子類別屬性之前。在傳回清單之前,會移除重複的屬性。
注意:此清單用於 $class->new(\@ARRAY)
建構函式,以決定每個值要配對的屬性。
HashBase 的原始程式碼存放庫位於 http://github.com/Test-More/HashBase/。
版權所有 2017 Chad Granum <exodist@cpan.org>。
此程式為自由軟體;您可以在與 Perl 相同的條款下重新散布或修改它。
請參閱 http://dev.perl.org/licenses/