如何在perl中的对象内创建对象列表?

时间:2016-11-01 21:31:20

标签: list perl class object module

我是Perl的新手,对不起我的愚蠢问题。

我搜索了但我没有找到办法做到这一点。

我创建了一个类,一个属性需要是一个对象列表,我需要稍后调用此列表。

我试图将列表中的对象推送到收到消息:

匿名哈希中奇数个元素的数量......

我的包裹

package Squid;

use strict;
use warnings;

sub new
{
  my $class = shift;
  my $self = {@_ };

  print "Creating new $class\n";

  $self->{'filas'} = [];

  bless ($self, $class);

  return $self;
}

1;

这是剧本:

use Squid;
use warnings;
use strict;


my $fila = FilaSquid->new("nome" => 'Fila 1', "profundidade" => 45);
my $fila2 = FilaSquid->new("nome" => 'Fila 2', "profundidade" => 7);

my $squid = Squid->new("versao" => '1.0', "origem" => 'C:\temp', "filas" => @filas);

print "\nA versao da fila eh ".$squid->{versao};
print "\nA origem da fila eh ".$squid->{origem}."\n";

foreach my $line ($squid->{filas}) {
    print $line->{nome}."\n";
}

2 个答案:

答案 0 :(得分:6)

第一个问题是new

$self->{'filas'} = [];

您正在将$self->{'filas'}初始化为空数组引用。这将吹走通过new传递的任何内容。你可能想要的是:

$self->{filas} //= [];

与以下内容相同:

$self->{filas} = $self->{filas} // [];

// is the "defined-or" operator。这表示如果未定义,则仅初始化$self->{filas}。它比使用||=更安全,因为有一些有效的东西是错误的。

第二个问题是你如何将filas传递给new。您正在使用数组引用初始化$self->{filas}是您的线索。

my @filas = (1, 2, 3, 4, 5, 6);

my $squid = Squid->new(
    "versao" => '1.0',
    "origem" => 'C:\temp',
    "filas" => @filas
);

这就像说:

my $squid = Squid->new(
    "versao" => '1.0',
    "origem" => 'C:\temp',
    "filas" => 1,
    2, 3, 4, 5, 6
);

你刚刚在一个偶数大小的列表的末尾添加了一大堆东西用作哈希。

=>运算符与逗号基本相同。它不会创建对,它只允许您在左侧的字符串周围省略引号。 key => @values不是一对,而是key => $values[0], $values[1], $values[2], ...new尝试将该列表视为哈希值,只要存在偶数个元素就会“起作用”。

相反,您需要传入一个数组引用key => \@values

my $squid = Squid->new(
    "versao" => '1.0',
    "origem" => 'C:\temp',
    "filas" => \@filas
);

答案 1 :(得分:1)

这是一种可以在不破坏封装的情况下将大量对象插入另一个对象的方法。它不关注现有代码中的任何问题,只是回答了问题。在此示例中,Two包含许多类One的对象。每个内部对象都有一个名称:

use warnings;
use strict;

package One; {
    sub new {
        my ($class, %args) = @_;
        return bless {%args}, $class;
    }
    sub name {
        my $self = shift;
        return $self->{name};
    }
}

package Two; {
    sub new {
        return bless {}, shift;
    }
    sub add {
        my ($self, %args) = @_;
        my $name = $args{name};
        $self->{objects}{$name} = One->new(name => $name);
    }
    sub get_names {
        my ($self) = @_;
        return keys %{ $self->{objects} };
    }
    sub inner_obj {
        my ($self, $name) = @_;
        return $self->{objects}{$name};
    }
}

package main;

my $two = Two->new;

$two->add(name => 'obj1');
$two->add(name => 'obj2');

# loop over each inner object by name

for my $name ('obj1', 'obj2'){
    print $two->inner_obj($name)->name . "\n";
}

# or let Two give you the list of names back, and iterate
# automatically

for ($two->get_names){
    print $two->inner_obj($_)->name . "\n";
}

请注意,我们在主脚本中手动添加新对象。如果您需要在模块中设置对象列表而不是主要内容,那就简单了......您只需修改Two::new()以在内部调用其add()方法。