【问题标题】:Perl - Object value not savedPerl - 对象值未保存
【发布时间】:2010-05-25 19:34:20
【问题描述】:

试图掌握在 Perl 中使用 OOP 的窍门。我的问题是我在类中设置了一个变量,但是当我尝试检索它时该值丢失了。我确定这个问题很明显,但我需要一些额外的眼睛。

构造函数:

sub new
{
    my ($class, $name) = @_;
    my $self = {
        _name => $name,
        _times => []
    };
    bless ($self, $class);
    return $self;
}

访问器/修改器方法:

sub times {
    my ($self) = shift;
    if (@_) { @{$self->{_times}} = shift }
    print "times size: " . @{$self->{_times}} . "\n";
    return @{$self->{_times}};
}

从主程序调用:

$js->addRun($duration, $curStartTime);
print "Times size: " . @{$js->times()} . "\n";

addRun() 子程序的相关代码:

sub addRun {
    my ($self, $duration, $runDateTime) = @_;
    if (!defined($duration) || !defined($runDateTime)) { return 0; }
    push(@{$self->{_times}},$duration);
}

当我运行此代码时,它进入 addRun 子例程并将值推送到 _times 变量。然后我通过调用访问器/修改器来打印该值。但是访问器/修改器有自己的打印命令,所以我可以在返回之前检查它的值。

访问器打印正确的值,但是当我打印返回的值时,它是未定义的。我的语法在某处搞砸了吗?我只是个白痴吗?

谢谢

【问题讨论】:

  • 您是否尝试在对象上使用 Data::Dumper 来查看该值是否真的被保存了?

标签: perl


【解决方案1】:

问题出在你的 times() 子例程中,你返回的是一个数组,而不是数组引用。

然后在您的主程序中,您尝试取消对 times() 的调用,但您不需要这样做。

所以在你的主程序中调用它如下:-

print "Times size: " . $js->times() . "\n";

【讨论】:

  • +1。你应该返回一个数组吗?您可能需要阅读 wantarray 以使您的代码更具上下文感知能力。
  • 太棒了,把它修好了。这就是我在没有完全理解它的情况下使用语法所得到的。我想我遇到了一个需要取消引用的问题,所以我一定对这个想法发疯了。谢谢
  • @Konerak,为什么要打扰wantarray?为什么不直接返回数组并让上下文做它应该做的事情呢?例如,如果times 返回数组,它将获取标量上下文中的大小和列表中的内容。就像一个普通的数组。如果你想要一个数组引用,你可以使用my $bar = [$foo->times];,这几乎就是你需要对wantarray 做的事情,除非你想打破对对象的封装。
  • perl OOP 教程使用我使用的语法(返回数组,而不是数组引用)perldoc.perl.org/perltoot.html
【解决方案2】:

我在启用use strict; 的情况下尝试了您的代码并获得了Can't use string ("1") as an ARRAY ref while "strict refs" in use

它指的是行:print "Times size: " . @{$js->times()} . "\n";

times 方法返回一个值数组。当您取消引用时间的返回值时,您正在给它一个标量上下文。因此对数组进行求值以给出数组中的成员数,即 1。所以您正在尝试访问不存在的 @'1'。

这是您的代码的清理版本。您有几个错误(通过 times 方法设置时,不可能有一个长度 > 1 的数组。

#!/usr/bin/perl 

use strict;
use warnings;

my $foo = Foo->new('Pogo');

$foo->addRun( 10, time );
$foo->addRun( 20, time );
print "Times: ", join( ' ', $foo->times ), "\n";
print "Times length: " . $foo->times . "\n";


BEGIN {
    package Foo;

    sub new {
        my ($class, $name) = @_;
        my $self = {
            _name => $name,
            _times => [],
        };
        bless $self, $class;
        return $self;
    }

    sub times {
        my $self = shift;
        if (@_) { 
            my $time_array = shift;
            @{$self->{_times}} = @{$time_array};
        }
        return @{$self->{_times}};
    }

    sub add_times {
        my $self = shift;
        return push @{$self->{_times}}, @_;
    }

    sub addRun {
        my ($self, $duration, $runDateTime) = @_;

        return 0 unless defined($duration) and defined($runDateTime);

        $self->add_times($duration);
    }

}

【讨论】:

  • 你的意思是告诉我use strict 会让这个错误变得不可能?太棒了!
猜你喜欢
  • 2013-09-16
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多