2010-05-25 10 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 변수에 푸시합니다. 그런 다음 접근 자/변경자를 호출하여 값을 인쇄합니다. 하지만 액세서/뮤 테이터에는 자체 인쇄 명령이 있으므로 반환하기 전에 값을 확인할 수 있습니다.

접근자가 올바른 값을 인쇄하지만 반환 된 내용을 인쇄 할 때 정의되지 않습니다. 내 구문 어딘가 엉망 이냐? 나는 바보 야?

감사

+0

몇 가지 오류가 있었다 당신은 값이 정말 거지 있는지 확인하기 위해 개체에 데이터 :: 덤퍼를 사용하여 시도해 봤어 – Ether

+1

'strict' 프라그마를 활성화하십시오 – daotoad

답변

9

문제는 당신의 시간() 서브 루틴은 배열이 아니라 배열 참조를 반환하는입니다.

다음 주 프로그램에서 times() 호출을 역 참조하려고하지만 필요는 없습니다. 다음과 같이

그래서 메인 프로그램에서 그냥 전화 : -

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

+1 배열을 반환해야합니까? wantarray를 읽고 상황에 맞는 코드를 만들 수 있습니다 – Konerak

+0

괜찮아요, 바로 잡았습니다. 문법을 완전히 이해하지 않고 사용하는 것입니다. 역 참조가 필요한 곳에 문제가 발생했다고 생각합니다. 따라서 생각이 미쳐야합니다. 감사합니다. – brydgesk

+0

@Konerak, 왜 wantarray를 사용합니까? 배열과 문맥이해야 할 일을하도록하라. 예를 들어,'times'가 배열을 반환하면, 스칼라 컨텍스트의 크기와 list의 내용을 가져옵니다. 마치 정상 배열처럼.배열 ref를 원한다면'my $ bar = [$ foo-> times];'를 쓸 수 있습니다. 이것은 객체에 대한 캡슐화를 중단하기를 원하지 않는 한'wantarray'로해야 할 일입니다 . – daotoad

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에 액세스하려고합니다.

다음은 코드 정리 버전입니다. 있습니다 (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'는이 버그를 불가능하게 만들었다 고 말하고 싶습니까? 놀랄 만한! – friedo

관련 문제