Moose:对象数组->遍历属性
Moose: Array of Objects->loop through Attribute
我是 Perl Moose 的新手,我正在尝试完成这个简单的任务。我有我的驼鹿 class "TestObject" 定义:
package TestObject;
use Moose;
use namespace::autoclean;
has 'Identifier' => (is =>'ro',isa=>'Str');
around BUILDARGS => sub
{
my $orig = shift;
my $class = shift;
if ( @_ == 1 && ! ref $_[0] ) {
return $class->$orig(Identifier => $_[0]);
}
else {
return $class->$orig(@_);
}
};
__PACKAGE__->meta->make_immutable;
1;
在另一个脚本中,我试图直接从 "TestObjects":
的数组访问属性 "Identifier"
use TestObject;
use experimental 'smartmatch';
my @aArray1=(TestObject->new("z003"),TestObject->new("t302"),TestObject->new("r002"));
my $sIdent="t302";
if($sIdent~~@aArray1->Identifier)
{
print "Element with Identifier".$sIdent." found.";
}
这行不通。我可以实施这样的解决方法:
my @aIdent=();
foreach my $sObject(@aArray1)
{
push(@aIdent,$sObject->Identifier);
}
if($sIdent~~@aIdent)
{
print "Element with Identifier".$sIdent." found.";
}
但这似乎不是最优雅的解决方案。解决这个问题最优雅的方案是什么?
不要使用智能匹配运算符执行此操作。它出于某种原因是实验性的,它可能会从未来的 Perl 版本中删除,或者像以前一样改变它的工作方式。
相反,这可以通过简单的 grep
来实现。
my @aArray1 = (
TestObject->new("z003"),
TestObject->new("t302"),
TestObject->new("r002"),
);
my $sIdent = "t302";
if ( grep { $_->Identifier eq $sIdent } @aArray1 ) {
print "Element with Identifier" . $sIdent . " found.";
}
如果你想让它更短一些,你也可以使用 first
from List::Util。这会快一点,因为它会在第一场比赛结束后停止寻找。
use List::Util 'first';
my @aArray1 = (
TestObject->new("z003"),
TestObject->new("t302"),
TestObject->new("r002"),
);
my $sIdent = "t302";
if ( first { $_->Identifier eq $sIdent } @aArray1 ) {
print "Element with Identifier" . $sIdent . " found.";
}
关于您的代码的几点建议:
- 永远不要用 object 命名 class 任何东西。这会让你、未来的你和维修人员感到困惑。如果您不明白 class 和 object 之间的区别,请继续阅读。
- Perl 中的变量名和函数总是按照惯例用小写字母书写,我们使用蛇形。驼峰大小写保留用于包名称。
我是 Perl Moose 的新手,我正在尝试完成这个简单的任务。我有我的驼鹿 class "TestObject" 定义:
package TestObject;
use Moose;
use namespace::autoclean;
has 'Identifier' => (is =>'ro',isa=>'Str');
around BUILDARGS => sub
{
my $orig = shift;
my $class = shift;
if ( @_ == 1 && ! ref $_[0] ) {
return $class->$orig(Identifier => $_[0]);
}
else {
return $class->$orig(@_);
}
};
__PACKAGE__->meta->make_immutable;
1;
在另一个脚本中,我试图直接从 "TestObjects":
的数组访问属性 "Identifier"use TestObject;
use experimental 'smartmatch';
my @aArray1=(TestObject->new("z003"),TestObject->new("t302"),TestObject->new("r002"));
my $sIdent="t302";
if($sIdent~~@aArray1->Identifier)
{
print "Element with Identifier".$sIdent." found.";
}
这行不通。我可以实施这样的解决方法:
my @aIdent=();
foreach my $sObject(@aArray1)
{
push(@aIdent,$sObject->Identifier);
}
if($sIdent~~@aIdent)
{
print "Element with Identifier".$sIdent." found.";
}
但这似乎不是最优雅的解决方案。解决这个问题最优雅的方案是什么?
不要使用智能匹配运算符执行此操作。它出于某种原因是实验性的,它可能会从未来的 Perl 版本中删除,或者像以前一样改变它的工作方式。
相反,这可以通过简单的 grep
来实现。
my @aArray1 = (
TestObject->new("z003"),
TestObject->new("t302"),
TestObject->new("r002"),
);
my $sIdent = "t302";
if ( grep { $_->Identifier eq $sIdent } @aArray1 ) {
print "Element with Identifier" . $sIdent . " found.";
}
如果你想让它更短一些,你也可以使用 first
from List::Util。这会快一点,因为它会在第一场比赛结束后停止寻找。
use List::Util 'first';
my @aArray1 = (
TestObject->new("z003"),
TestObject->new("t302"),
TestObject->new("r002"),
);
my $sIdent = "t302";
if ( first { $_->Identifier eq $sIdent } @aArray1 ) {
print "Element with Identifier" . $sIdent . " found.";
}
关于您的代码的几点建议:
- 永远不要用 object 命名 class 任何东西。这会让你、未来的你和维修人员感到困惑。如果您不明白 class 和 object 之间的区别,请继续阅读。
- Perl 中的变量名和函数总是按照惯例用小写字母书写,我们使用蛇形。驼峰大小写保留用于包名称。