我对Perl很新,所以请耐心等待......我最近看到一个使用Class::Struct
的脚本:
#!/usr/bin/perl
package Animal;
use strict;
use warnings;
use Class::Struct;
struct Animal => {
species => '$'
};
sub species {
print "In species";
}
package main;
my $x;
$x = Animal->new;
输出:物种
我的理解是,这基本上是以下的捷径:
#!/usr/bin/perl
package Animal;
use strict;
use warnings;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
sub species {
print "In species";
}
package main;
my $x;
$x = Animal->new;
输出:
我没想到Class::Struct
示例输出:物种。这似乎表明结构中列出的所有子/方法都在运行Animal->new
时运行,但我不确定为什么会出现这种情况。我希望Class::Struct
只创建访问器方法,并为我提供一个new
方法来获取对象引用。
所以我的问题是:
Class::Struct
在初始化时运行所有方法?更新 在Perl 5.18.0之前,这不是默认行为,如下所示:https://rt.perl.org/Public/Bug/Display.html?id=29230
答案 0 :(得分:4)
如果您有一个名为species
的属性,Class:Struct
会为此设置名为species
的访问者,并且它还会调用该访问者以在对象期间使用undef
对其进行初始化构造:
struct数据中的每个元素都有一个访问器方法,用于分配元素并获取其值。可以通过在包中声明具有相同名称的sub来覆盖默认访问器。 (见例2)
...
标量(
'$'
或'*$'
)元素是标量,默认情况下初始化为
undef
您通过定义名为species
且不是访问者的子项来混淆该过程。您永远无法设置species
字段的值,并且每次尝试阅读species
的值时,您都会获得1
和#34} ;在物种"正在印刷,这只会使事情混乱。
事实上,运行你的例子已经告诉你发生了什么:
function 'species' already defined, overrides struct accessor method at ./struct.pl line 10.
#!/usr/bin/perl
package Animal;
use strict;
use warnings;
use Class::Struct;
struct Animal => {
species => '$'
};
package main;
my $x;
$x = Animal->new;
$x->species('specious');
print $x->species, "\n";
所以,回答你的问题:
- 为什么
Class::Struct
在初始化时运行所有方法?
它没有运行所有方法。它正在使用访问器初始化对象,因为良好的封装需要。
答案 1 :(得分:4)
取自Class::Struct's documentation:
struct数据中的每个元素都有一个访问器方法,用于分配元素并获取其值。可以通过在包中声明具有相同名称的sub来覆盖默认访问器。 (见例2)
后来(重点补充):
标量('$'或'* $')
元素是标量,默认情况下初始化为undef (但请参阅“使用new初始化”)。
将访问者的参数(如果有)分配给元素。
new
调用尝试通过调用程序包中定义的访问者子species
将species
属性设置为undef。
作为访问者例程中的Dumper调用显示:
sub species {
print "In species\n";
use Data::Dumper;
print Dumper(\@_);
}
输出:
In species
$VAR1 = [
bless( {}, 'Animal' ),
undef
];