动态添加前导下划线到现有子
dynamically add leading underscore to existing sub
在这个 perl 书的例子中,“_components”来自哪里?
我知道添加 _ 以指示 sub 对包是私有的,但是这个似乎无处不在地使用领先分数。你能给我指出一些关于这个的消息来源吗?谢谢。
package Computer;
@ISA = qw(StoreItem);
sub new {
my $pkg = shift;
my $obj = $pkg->SUPER::new("Computer", 0,0);
$obj->{_components} = [];
$obj->components(@_);
$obj;
}
sub components {
my $obj = shift;
@_ ? push (@{$ojb->{_components}}, @_) : @{$obj->{_components}};
}
sub price {
my $obj = shift;
my $price = 0;
my $component;
for my $component ($obj->components()) {
$price += $component->price();
}
$price;
}
_components
是 $obj
散列引用的文字键。它不是“来自”任何地方。这是 Perl 语法的一个怪癖。在声明中
$obj->{_components} = [];
$obj
是对 class 的新创建实例的引用(在前面的语句中),并且 _components
被定义为该实例中的键,并被初始化对空数组的引用。这相当于
$obj->{'_components'} = [];
例如
$ perl -de0
Loading DB routines from perl5db.pl version 1.55
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 0
DB<1> $obj->{a} = "hello";
DB<2> x $obj
0 HASH(0x800756bf8)
'a' => 'hello'
DB<3> p $obj->{'a'}
hello
DB<4> p $obj->{a}
hello
DB<5>
_components
只是程序员选择的文字键名。之后,调用 components
可以访问刚刚创建的密钥。
部分问题是界面。 $obj->{_components}
处理非常低级别的细节,而 $self->components
是更高级别的细节。我不是特别喜欢混合抽象层次。
原始代码 components
根据参数列表的大小进行设置和获取。通过 autovivification,它会自动初始化 $obj->{_components}
,所以你不需要 $obj->{_components} = []
行,除了设置第一个调用:
sub components {
my $obj = shift;
@_ ? push (@{$obj->{_components}}, @_) : @{$obj->{_components}};
}
但是,对于在设置任何组件之前不带参数调用的情况,我会在 components
中对其进行初始化:
sub components {
my $obj = shift;
$obj->{_components} = [] unless $obj->{_components};
@_ ? push (@{$obj->{_components}}, @_) : @{$obj->{_components}};
}
使用 postfix deref 更简单:
use v5.26;
sub components {
my $obj = shift;
$obj->{_components} = [] unless $obj->{_components};
@_ ? push ( $obj->{_components}->@* , @_) : $obj->{_components}->@*;
}
但我会改变它。 push
return 是一个数字,这可能不是您想要的界面。摆脱条件运算符并始终 return 最后的完整列表:
use v5.26;
sub components {
my $obj = shift;
$obj->{_components} = [] unless $obj->{_components};
push $obj->{_components}->@* , @_ if @_;
$obj->{_components}->@*;
}
并且,回到您最初的查询:该键只是程序员选择的一个字符串。通常 _
出现在键之前,以表明它是元数据或其他将被忽略的东西。我不知道这里的意图。不要多次输入,定义一次:
use v5.26;
sub components {
state $key = '_components';
my $obj = shift;
$obj->{$key} = [] unless $obj->{$key};
push $obj->{$key}->@* , @_ if @_;
$obj->{$key}->@*;
}
使用 experimental signatures feature 可以稍微清理一下:
use v5.26;
use experimental qw(signatures);
sub components ($self, @args) {
state $key = '_components';
$obj->{$key} = [] unless $obj->{$key};
push $obj->{$key}->@* , @args if @arg;
$obj->{$key}->@*;
}
在这个 perl 书的例子中,“_components”来自哪里? 我知道添加 _ 以指示 sub 对包是私有的,但是这个似乎无处不在地使用领先分数。你能给我指出一些关于这个的消息来源吗?谢谢。
package Computer;
@ISA = qw(StoreItem);
sub new {
my $pkg = shift;
my $obj = $pkg->SUPER::new("Computer", 0,0);
$obj->{_components} = [];
$obj->components(@_);
$obj;
}
sub components {
my $obj = shift;
@_ ? push (@{$ojb->{_components}}, @_) : @{$obj->{_components}};
}
sub price {
my $obj = shift;
my $price = 0;
my $component;
for my $component ($obj->components()) {
$price += $component->price();
}
$price;
}
_components
是 $obj
散列引用的文字键。它不是“来自”任何地方。这是 Perl 语法的一个怪癖。在声明中
$obj->{_components} = [];
$obj
是对 class 的新创建实例的引用(在前面的语句中),并且 _components
被定义为该实例中的键,并被初始化对空数组的引用。这相当于
$obj->{'_components'} = [];
例如
$ perl -de0
Loading DB routines from perl5db.pl version 1.55
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 0
DB<1> $obj->{a} = "hello";
DB<2> x $obj
0 HASH(0x800756bf8)
'a' => 'hello'
DB<3> p $obj->{'a'}
hello
DB<4> p $obj->{a}
hello
DB<5>
_components
只是程序员选择的文字键名。之后,调用 components
可以访问刚刚创建的密钥。
部分问题是界面。 $obj->{_components}
处理非常低级别的细节,而 $self->components
是更高级别的细节。我不是特别喜欢混合抽象层次。
原始代码 components
根据参数列表的大小进行设置和获取。通过 autovivification,它会自动初始化 $obj->{_components}
,所以你不需要 $obj->{_components} = []
行,除了设置第一个调用:
sub components {
my $obj = shift;
@_ ? push (@{$obj->{_components}}, @_) : @{$obj->{_components}};
}
但是,对于在设置任何组件之前不带参数调用的情况,我会在 components
中对其进行初始化:
sub components {
my $obj = shift;
$obj->{_components} = [] unless $obj->{_components};
@_ ? push (@{$obj->{_components}}, @_) : @{$obj->{_components}};
}
使用 postfix deref 更简单:
use v5.26;
sub components {
my $obj = shift;
$obj->{_components} = [] unless $obj->{_components};
@_ ? push ( $obj->{_components}->@* , @_) : $obj->{_components}->@*;
}
但我会改变它。 push
return 是一个数字,这可能不是您想要的界面。摆脱条件运算符并始终 return 最后的完整列表:
use v5.26;
sub components {
my $obj = shift;
$obj->{_components} = [] unless $obj->{_components};
push $obj->{_components}->@* , @_ if @_;
$obj->{_components}->@*;
}
并且,回到您最初的查询:该键只是程序员选择的一个字符串。通常 _
出现在键之前,以表明它是元数据或其他将被忽略的东西。我不知道这里的意图。不要多次输入,定义一次:
use v5.26;
sub components {
state $key = '_components';
my $obj = shift;
$obj->{$key} = [] unless $obj->{$key};
push $obj->{$key}->@* , @_ if @_;
$obj->{$key}->@*;
}
使用 experimental signatures feature 可以稍微清理一下:
use v5.26;
use experimental qw(signatures);
sub components ($self, @args) {
state $key = '_components';
$obj->{$key} = [] unless $obj->{$key};
push $obj->{$key}->@* , @args if @arg;
$obj->{$key}->@*;
}