3

Perl オブジェクトにファイル ハンドルを格納したいと考えていました。これが私が行った方法です。

sub openFiles {
     my $self = shift;
     open (my $itemsFile, "<", "items.txt")     or die $!;
     open (my $nameFile,  "<", "FullNames.txt") or die $!;      
     $self->{itemsFile} = $itemsFile;                   
     $self->{nameFile}  = $nameFile;
     return $self;
}

次に、これらのファイルの 1 つからいくつかの情報にアクセスしようとしています。これが私がそれを行う方法です。

sub getItemDescription {
     my $self = @_;
     chomp(my $record = $self->{itemsFile});
     return $record;
}

次のように、別の手順でアクセスしようとします。

print "Test 3: $self->getItemDescription()\n";

私の質問は次のとおりです。

  1. ファイルハンドルをオブジェクトに保存する方法は正しいですか? そうでない場合、どのように間違っていますか?
  2. ファイルの行を読む方法は正しいですか? そうでない場合、どうすれば正しくなりますか?
  3. 最後に、返されたオブジェクトを印刷する方法は正しいですか?

これは私にとって本当に重要です。ファイル処理用のグローバル変数を作成したり、オブジェクトの構造を変更したりするなど、コードの構造を改善できる方法があれば教えてください。

4

3 に答える 3

4

ファイルハンドルをオブジェクトに保存する方法は正しいですか?

はい。

ファイルの行を読む方法は正しいですか?

いいえ、ファイル ハンドルを割り当てるだけです。readline演算子を使用してファイルから行を読み取ります。

通常は演算子の<...>構文を使用しますが、これは と の両方のショートカットであり、Perl は を の省略形と考えています。具体的に使用する必要がありますreadline<...>readline(...)glob(qq<...>)<$self->{itemsFile}>glob(qq<$self->{itemsFile}>)readline

my $record = readline($self->{itemsFile});
chomp($record) if defined($record);

または追加の作業を行います

my $fh = $self->{itemsFile};
my $record = <$fh>;
chomp($record) if defined($record);

( /は undef を返す可能性があるchompため、無条件に呼び出さないことに注意してください。)readline<>

最後に、返されたオブジェクトを印刷する方法は正しいですか?

によって返される文字列のように、返された文字列を意味していると思いますgetItemDescription。問題は、実際にメソッドを呼び出すことは決してないということです。->getItemDescription()変数の後であっても、二重引用符で囲まれた文字列リテラルでは意味がありません。$self->getItemDescription()二重引用符の外に移動する必要があります。

また、ファイルの最後に到達したかどうかも確認できません。

于 2013-01-16T04:37:51.847 に答える
2

あなたは近くにいます。

ファイルハンドルからレコード (行) を読み取るには、ファイルハンドルを「単純なスカラー」に割り当てた後で、組み込みreadline関数または<...>演算子を使用します (以下の編集を参照)。

chomp(my $record = readline( $self->{itemsFile} );

my $fh = $self->{itemsFile};
chomp(my $record = <$fh>);

メソッドにもバグがありますgetItemDescription。あなたは言いたくなるでしょう

my ($self) = @_;

それ以外の

my $self = @_;

後者の呼び出しは配列のスカラー割り当てであり、配列の最初の要素ではなく、配列の長さに解決されます。

編集:説明するよう<$self->{itemsFile}>、機能し<{$self->{itemsFile}}>ません:perlop

山括弧内がファイルハンドルでも、ファイルハンドル名、型グロブ、または型グロブ参照を含む単純なスカラー変数でもない場合、グロブされるファイル名パターン、およびファイル名のリストまたはリスト内の次のファイル名のいずれかとして解釈されます。コンテキストに応じて返されます。この区別は、構文上の理由だけで決定されます。つまり、<$x>は常にreadline()間接ハンドルからの ですが、<$hash{key}>常にglob()です。これ$xは単純なスカラー変数であるためですが、そう$hash{key}ではなく、ハッシュ要素です。偶数<$x >(余分なスペースに注意してください) はglob("$x ")ではなくとして扱われreadline($x)ます。

于 2013-01-16T04:39:17.957 に答える
0

openFilesピースは正しいです。

エラーは主にgetItemDescriptionメソッドで発生します。

まず、前述のmy $self = @_;ようにmy ($self) = @_;.

ただし、問題の核心は次の方法で解決されます。

chomp(my $record = $self->{itemsFile});次の 2 行に変更します。

$file1 = $self->{itemsFile};

chomp(my $record = $file1);

明確にするために、(私の経験では、提案されたすべてのソリューションを試しました)スカラー値を使用する必要があります。

最後に、ikagami の回答の最後の 2 つの段落を参照してください。

于 2013-01-23T14:55:44.250 に答える