1

以前は気にしていなかった 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 に慣れていませんが、誰か答えてもらえますか?

編集

サンプル人事:

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

編集

ケースクローズ..私の回答投稿を読んでください

4

3 に答える 3

3

上記のコメントから、それぞれが問題を解決し.''た後に追加します。substrこれは->hr、、、->minおよび->secメソッドが何らかの方法で引数を変更しているためです。さらに詳しく見ないと、何が起こっているのかはっきりとは言えません。

このsubstr関数は、有効な左辺値である値を返します。これは、に割り当てることができることを意味します。したがって、これらのメソッドの何かが substr からのスライスに割り当てられると、他のメソッドに干渉します。

空の文字列を追加すると、スライスと元の文字列 ( に格納されている$intime) の間のエイリアスが壊れて問題が修正されます。

およびメソッドを作成した場合は、hrそれらが引数を変更している理由を理解する必要があります。各メソッド呼び出しの間にステートメントを追加すると、明らかになるはずです。minsecprint "[$intime]\n";

于 2011-02-01T06:57:00.843 に答える
1

問題を示す自己完結型の実行可能なコードを思い付くことができますか? あなたが説明した問題は、あなたが示したコードと完全には一致しませんが、あなたのコードでの @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";
于 2011-02-01T08:50:45.270 に答える
0

この問題は解決されました。

substrを次のように使用する方法は、エラーなしで正常に実行できます。

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

ただし、このスクリプトが失敗したのは、末尾に空白行があるログファイルです。

問題を再現するように依頼してくれた@ysthに感謝します。問題が実際にはスクリプトではなく、ログファイルにあることに気づきました。

教訓:問題を提起する前に、コードとソースを確認してください

于 2011-02-01T09:01:32.187 に答える