2010-05-25 47 views
1

嘗試在Perl中使用OOP。我的問題是我在課堂上設置了一個變量,但是當我嘗試並檢索它時,該值會丟失。我確定這個問題很明顯,但我需要一些額外的眼睛。Perl - 未保存對象值

構造:

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

存取/突變方法:

$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); 
} 
從主程序

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

呼叫

當我運行這段代碼時,它進入addRun子程序並將值推送到_times變量。然後通過調用訪問器/增變器來打印值。但是accessor/mutator有自己的打印命令,所以我可以在返回之前檢查它的值。

訪問器打印正確的值,但是當我打印返回的內容時,它是未定義的。我的語法是在哪裏搞亂的?我只是一個白癡?

感謝

+0

你試試用你的對象上的數據::自卸車,看看是否值確實得到保存? – Ether 2010-05-25 20:01:00

+1

啓用'strict'編譯指示。 – daotoad 2010-05-25 20:05:44

回答

9

的問題是在你的時間()子程序你是返回一個數組,而不是一個數組引用。

然後在你的主程序中,你正嘗試將調用解引用到times(),但你並不需要。

所以在你的主程序只需要調用它,如下所示: -

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

+1。你應該返回一個數組嗎?你可能想要閱讀wantarray,以使你的代碼更容易識別上下文。 – Konerak 2010-05-25 19:46:36

+0

真棒,修正了它。因爲在沒有完全理解的情況下使用語法,我想我遇到了需要解除引用的一個問題,所以我一定是爲這個想法而瘋狂了。 謝謝 – brydgesk 2010-05-25 19:50:23

+0

@Konerak,爲什麼還要用wantarray呢? e數組並讓上下文做它應該做的事情?例如,如果'times'返回數組,它將得到標量上下文中的大小以及列表中的內容。就像一個普通的數組一樣。如果你想要一個數組ref,你可以執行'my $ bar = [$ foo-> times];',這幾乎是你需要做的事情'wantarray',除非你想破壞對象的封裝。 – daotoad 2010-05-25 20:04:41

4

我想你的代碼啓用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); 
    } 

} 
+2

你的意思是告訴我'use strict'會使這個bug變得不可能嗎?驚人! – friedo 2010-05-25 20:30:02