【问题标题】:Moose: Array of Objects->loop through AttributeMoose:对象数组->遍历属性
【发布时间】:2017-09-08 19:50:34
【问题描述】:

我是 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;

在另一个脚本中,我试图直接从“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.";
}

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

【问题讨论】:

  • 不要将你的类命名为 Object。这真是令人困惑!
  • 我会说不要使用智能匹配运算符。它是实验性的,最终可能会改变或被淘汰。

标签: arrays perl attributes moose


【解决方案1】:

不要使用 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 命名一个类。这会让你、未来的你和维修人员感到困惑。如果您不了解 classobject 之间的区别,请阅读。
  • 按照惯例,Perl 中的变量名和函数总是小写,我们使用蛇形大小写。为包名保留驼峰式大小写。

【讨论】:

  • "永远不要用对象命名一个类。"我的第一份工作是研究数据建模工具的数据库生成组件。我们的数据库有称为“数据库”、“表”和“列”的表。这非常令人困惑!
  • @simbabque:谢谢您的回答。是的,我知道类和对象之间的区别,只是写了这段代码 sn-p 用于在 stackoverflow 上发布。你能帮我解决类似的问题吗?我正在努力将 grep 语法实现到 List::Compare 对象中: my $lc=List::Compare->new('-u',\@aIdentList,\@{(grep {$_->Identifier} @aArray1)});
  • @airborne 请为此提出一个新问题。
  • @airborne:“我知道类和对象之间的区别,刚刚写了这段代码 sn-p 用于在 stackoverflow 上发布” 我们如何如此特别以至于我们应该感到困惑版本?
猜你喜欢
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 2021-08-28
  • 1970-01-01
相关资源
最近更新 更多