Почему substr работает по-разному при передаче непосредственно в метод? - PullRequest
1 голос
/ 01 февраля 2011

У меня есть вопрос о Perl, о котором я раньше не беспокоился, но сейчас он меня беспокоит.

У меня есть вызов метода saveItems, который получает значение из текстового журнала и анализируетвходные данные.

поэтому у меня есть несколько строк в методе.

$intime  = $_[1];
$timeHr  = substr($intime, 0,2); 
$timeMin = substr($intime, 2,2);
$timeSec = substr($intime, 5,2);
$object[$_[0]]->hr($timeHr);
$object[$_[0]]->min($timeMin);
$object[$_[0]]->sec($timeSec);

$ intime - это значение времени, прошедшего в этот метод.Пример $ intime: 0431: 12

Мой вопрос таков: почему вышеизложенное не дает мне никакой ошибки, а когда я пытаюсь сократить строки следующим образом:

$object[$_[0]]->hr(substr($intime, 0,2));
$object[$_[0]]->min(substr($intime, 2,2));
$object[$_[0]]->sec(substr($intime, 5,2));

Только первоеодин работает, в то время как остальные дают мне ошибку вне строки.

Я относительно новичок в Perl, как вы можете видеть, но может ли кто-нибудь дать мне ответ на этот вопрос?

РЕДАКТИРОВАТЬ

Образец HR:

sub hr {
    my $self = shift;
    if (@_) { $self->{HR} = shift }
    return $self->{HR};
}

РЕДАКТИРОВАТЬ

Дело закрыто .. Прочитайте мой ответ пост

Ответы [ 3 ]

3 голосов
/ 01 февраля 2011

Из комментариев выше, добавление .'' после каждого substr решило вашу проблему. Причина этого заключается в том, что методы ->hr, ->min и ->sec каким-то образом модифицируют свой аргумент. Не видя этого дальше, я не могу точно сказать, что происходит.

Функция substr возвращает значение, которое является допустимым значением lvalue. Это означает, что оно может быть назначено. Поэтому, когда что-то в этих методах присваивается срезу из substr, это мешает другим методам.

Добавление пустой строки устраняет проблему, разбивая псевдоним между срезом и исходной строкой (хранится в $intime).

Если вы написали методы hr, min и sec, вы должны выяснить, почему они модифицируют свои аргументы. Добавление операторов print "[$intime]\n"; между каждым вызовом метода должно показывать.

1 голос
/ 01 февраля 2011

Можете ли вы придумать автономный исполняемый код, который демонстрирует проблему?Проблема, которую вы описываете, не совсем совпадает с кодом, который вы показываете, хотя я не понимаю роли @ object в вашем коде.

Следующее прекрасно работает:

use strict;
use warnings;

package Class;

sub new { bless {} }

sub saveItems {
    my $intime = $_[1];
    $_[0]->hr(substr($intime, 0,2));
    $_[0]->min(substr($intime, 2,2));
    $_[0]->sec(substr($intime, 5,2));
}

sub hr {
    my $self = shift;
    if (@_) { $self->{HR} = shift }
    return $self->{HR};
}

sub min {
    my $self = shift;
    if (@_) { $self->{MIN} = shift }
    return $self->{MIN};
}

sub sec {
    my $self = shift;
    if (@_) { $self->{SEC} = shift }
    return $self->{SEC};
}

package main;

my $object = Class->new();
$object->saveItems( '0431:12' );
print "hr: ", $object->hr(), " min: ", $object->min(), " sec: ", $object->sec(), "\n";
0 голосов
/ 01 февраля 2011

Этот вопрос был решен.

Способ использования substr, описанный ниже, может работать нормально, без ошибок.

$object[$_[0]]->hr(substr($intime, 0,2)); 
$object[$_[0]]->min(substr($intime, 2,2)); 
$object[$_[0]]->sec(substr($intime, 5,2)); 

Однако это файл журнала, который имеетзавершающие пустые строки, которые приводили к сбою этого скрипта.

Спасибо @ysth за просьбу воспроизвести проблему, когда я понял, что проблема на самом деле заключается в файле журнала, а не в скрипте.

Извлеченный урок: проверьте коды и источник, прежде чем поднимать вопрос

...