【问题标题】:Another simple Perl question...(hash to an array of objects)另一个简单的 Perl 问题...(散列到对象数组)
【发布时间】:2011-07-01 18:13:21
【问题描述】:

我正在使用 Perl 创建一个 Graph 类,我希望每个 Graph 都包含节点。每个节点都有一些属性,并且(目前)还有一个数组,其中包含对它所连接的每个其他节点的引用。到目前为止,我有一个节点的定义:

使用严格; 包节点;

sub new{
my $class = shift;
my @array = ();
my $array_r = \@array;
my $self = {
    code => undef,
name => undef,
country => undef,
continent => undef,
timezone => undef,
coordinates => undef
population => undef,
region => undef,
arrayRef => $array_r,
@_,

}; 祝福 $self, $class; 返回 $self; } 然而,在我的主脚本中调用以下函数时:

sub getSetArray{
    my $self = shift;
my $param = shift;
my $temp = $self->{arrayRef};
push(@{$temp}, $param) if defined $param;
return $self->{arrayRef};
} 

并尝试遍历节点的数组(其中将包含更多与其连接的节点):

my $firstnode = Node->new();  # Node constructor should have @array of
my $secondnode = Node->new();

$firstnode->getSetCode("test"); 
print "The current code is ", $firstnode->getSetCode(), "\n";

my $array_r = $firstnode->getSetArray($secondnode);

$array_r = $firstnode->getSetArray($firstnode);

foreach my $obj (@{$array_r}){
    print $obj;
}

这将打印出 Node=HASH(0x10092bb00)Node=HASH(0x100907bd8)。这让我相信我正在处理一个包含 2 个节点的数组(这就是我想要的)。但是在尝试调用这个 $obj 的任何方法时,我被告知我

不能在没有包或对象引用的情况下调用方法“getSetNode”。

我之前在这些节点上调用 new 时已经祝福了这两个对象。所以我不确定为什么它们不被识别为节点,我不能调用它们的方法......

编辑-

foreach my $obj (@{$array_r}){  
    print $obj->getSetCode();
}

getSetCode() 在哪里

sub getSetCode{
    my $self = shift;
    my $param = shift;
    $self->{code} = $param if defined $param;
    return $self->{code};
}

【问题讨论】:

    标签: arrays perl oop object hash


    【解决方案1】:

    展示你如何尝试在 $obj 上调用 getSetNode,以及 getSetNode 的代码?

    顺便说一句,$temp 不是必需的;你可以直接这样做:

    push @{ $self->{arrayRef} }, $param if defined $param;
    

    也许对你有帮助:http://perlmonks.org/?node=References+quick+reference

    还请注意,您正在设置一个循环数据结构($firstnode 间接引用自身),即使所有外部引用都消失了,perl 也不会自动收集垃圾;你可以解决这个问题(如果这甚至是一个问题):

    if (defined $param) {
        push @{ $self->{arrayRef} }, $param;
        Scalar::Util::weaken( $self->{arrayRef}[-1] ) if $param == $self;
    }
    

    就您的问题而言,将所有代码放在一起(并在坐标线上添加缺失的 , ):

    use warnings;
    use strict;
    package Node;
    
    sub new {
        my $class = shift;
        my @array = ();
        my $array_r = \@array;
        my $self = {
            code => undef,
            name => undef,
            country => undef,
            continent => undef,
            timezone => undef,
            coordinates => undef,
            population => undef,
            region => undef,
            arrayRef => $array_r,
            @_,
        };
        bless $self, $class;
        return $self;
    }
    
    sub getSetArray{
        my $self = shift;
        my $param = shift;
        my $temp = $self->{arrayRef};
        push(@{$temp}, $param) if defined $param;
        return $self->{arrayRef};
    } 
    
    sub getSetCode{
        my $self = shift;
        my $param = shift;
        $self->{code} = $param if defined $param;
        return $self->{code};
    }
    
    
    my $firstnode = Node->new();  # Node constructor should have @array of
    my $secondnode = Node->new();
    $secondnode->getSetCode("test2");
    
    $firstnode->getSetCode("test"); 
    print "The current code is ", $firstnode->getSetCode(), "\n";
    
    my $array_r = $firstnode->getSetArray($secondnode);
    
    $array_r = $firstnode->getSetArray($firstnode);
    
    foreach my $obj (@{$array_r}){  
        print $obj->getSetCode(), "\n";
    }
    

    给我这个输出:

    The current code is test
    test2
    test
    

    【讨论】:

    • 我添加了额外的函数信息
    • 这是我想要发生的,但不是我最终产生的输出。唯一的区别是 Node 类是在另一个名为 Node.pm 的文件中定义的,并且在 main.pl 文件中被“使用”。我宁愿将我的 Node 实现与 main.pl 文件分开。你知道为什么会发生这种情况吗? (此外,Node 构造函数中缺少逗号在我的代码中也不存在,并且在我编写问题时一定以某种方式丢失了)。
    • 我认为我遇到的最大问题是我将给定节点中的 @array 初始化为 undef。我将其更改为空列表 (),现在我正在让它工作。谢谢您的帮助。我学习 perl 大约有 5 个小时,但很多东西仍然不稳定。绝对是一门很酷的语言,我正在学习生物信息学课程,所以我可能会在那里看到它的力量。
    • 啊,是的,@array = undef 将单个 undef 元素放入数组中,该元素将无法成功调用方法。
    猜你喜欢
    • 2011-05-08
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 2013-04-13
    • 2013-12-30
    • 1970-01-01
    相关资源
    最近更新 更多