2010-05-25 3 views
1

Попытка получить поддержку использования ООП в Perl. Моя проблема в том, что я устанавливаю переменную в классе, но значение теряется, когда я пытаюсь ее восстановить. Я уверен, что проблема вопиющая, но мне нужны дополнительные глаза.Perl - значение объекта не сохранено

Конструктор:

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. Затем я печатаю значение, вызывая accessor/mutator. Но у аксессора/мутатора есть своя команда печати, поэтому я могу проверить значение, прежде чем возвращать его.

Аксессор печатает правильное значение, но когда я печатаю то, что было возвращено, оно не определено. Я где-то перепутал мой синтаксис? Я просто идиот?

Благодаря

+0

Пробовали ли вы с помощью Data :: Dumper на объект, чтобы увидеть, если значение действительно получить сохранен? – Ether

+1

Включить «строгую» прагму – daotoad

ответ

9

Проблемы в ваши раз (а) подпрограмме вы возвращаете массив, а не ссылки на массив.

Затем в вашей основной программе вы пытаетесь разыменовать вызов в times(), но вам не нужно.

Так в основной программе просто назвать его следующим образом: -

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

+1. Если вы возвращаете массив? Возможно, вы захотите прочитать на том, как сделать код более понятным для контекста. – Konerak

+0

Удивительно, исправил его прямо. Это то, что я получаю для использования синтаксиса без его полного понимания. Я думаю, что у меня возникла одна проблема, когда ее нужно было разыменовать, поэтому я, должно быть, сошел с ума от этой идеи. Спасибо – brydgesk

+0

@ Konerak, зачем беспокоиться о том, e array и позволить контексту делать то, что нужно? Например, если 'times' возвращает массив, он получит размер в скалярном контексте и содержимом в списке. Как обычный массив.Если вам нужен массив 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. Таким образом, вы пытаетесь получить доступ к @ '1', которого не существует.

Вот очищенная версия вашего кода. У вас было пару ошибок (это было невозможно когда-либо массив длины> 1 при установке с помощью метода times.

#!/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

Смежные вопросы