Moose:对象数组 - >遍历属性

时间:2017-09-08 11:38:38

标签: arrays perl attributes moose

我是Perl Moose的新手,我正在努力完成这项简单的任务。我有我的Moose课程" 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;

在另一个脚本中,我试图访问属性" Identifier"直接来自一组" TestObjects":

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.";
}

但这似乎并不是最优雅的解决方案。解决这个问题最优雅的解决方案是什么?

1 个答案:

答案 0 :(得分:4)

请勿使用smartmatch操作员执行此操作。它的实验有一个原因,它可能会从未来的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 object 之间的区别,请阅读。
  • Perl中的变量名称和函数总是按照惯例写成小写,我们使用snake case。 Camel case是为包名保留的。