如果我有一個 Perl 類,例如
package Foo;
sub new {
my ($class,$hashref) = @_;
my $self = bless $hashref, $class;
}
并初始化為
my $foo = Foo->new( { bar => 2, othervar => 8 } );
我可以
print $foo->{ bar };
感覺很笨重,并且
print $foo->bar
感覺更可取。但是,如果有很多鍵,我寧愿不必為每個鍵撰寫訪問器(或者這是最佳實踐)?
所以,我可以包括
our $AUTOLOAD;
sub AUTOLOAD {
my $self = shift;
my $called = $AUTOLOAD =~ s/.*:://r;
die "No such attribute: $called"
unless exists $self->{$called};
return $self->{$called};
}
sub DESTROY { } # see below
在 perldoc perlobj 它說
# XXX - this is a terrible way to implement accessors
有沒有什么好的方法來實作這樣的訪問器,而不使用其他包,例如 Moose、Class::Accessor ?我只是在追求一些輕巧的東西,因為它只是一個有很多鍵的類。
uj5u.com熱心網友回復:
有沒有什么好的方法來實作這樣的訪問器,而不使用其他包......
如果您堅持,則將這些 subs 直接寫入包符號表
package AutoAccessors;
use warnings;
use strict;
use feature 'say';
my @attr_names;
BEGIN {
@attr_names = qw(name mode etc);
no strict 'refs';
foreach my $accessor (@attr_names) {
*{$accessor} = sub { do {
if (@_ == 1) { $_[0]->{$accessor} }
elsif (@_ == 2) { $_[0]->{$accessor} = $_[1] }
#elsif ...
} };
}
};
sub new {
my ($class, $args) = @_;
my $self;
foreach my $attribute (@attr_names) {
# Check, initialize, set from $args, etc
$self->{$attribute} = $args->{$attribute} if $args->{$attribute};
}
return bless $self, $class;
}
1;
然后
use warnings;
use strict;
use feature 'say';
use AutoAccessors;
my $obj = AutoAccessors->new({ mode => '007' });
$obj->name('Bond');
say "name's ", $obj->name;
say "mode: ", $obj->mode;
這是在許多 CPAN 包中完成的(通常更復雜)。
話雖如此,我認為沒有充分的理由避免使用更好的庫,更仔細地完成和完成。例如,作為一個完整系統的Moo大約有 5 kloc(如果我沒記錯的話)并且幾乎沒有幾個依賴項,而Class::Accessor只有超過200 個 loc,我可以看到一個依賴項。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/506220.html
