3

私は File::Slurp モジュールを初めて使いました。最初のテストでは、期待していた結果が得られませんでした。それを理解するのにしばらく時間がかかったので、なぜこの特定の動作が見られたのかに興味があります。

File::Slurp への私の呼び出しは次のようになりました:

my @array = read_file( $file ) || die "Cannot read $file\n";

ファイルを開くときに「死ぬ」部分を使用することに慣れているため、「死ぬ」部分を含めました。私の @array は、配列の最初の要素にあるファイルの内容全体で常に終了します。最後に「|| die」セクションを取り出したところ、期待どおりに動作し始めました。

以下に例を示します。

perl -de0

Loading DB routines from perl5db.pl version 1.22
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1):   0
DB<1> use File::Slurp

DB<2> $file = '/usr/java6_64/copyright'

DB<3> x @array1 = read_file( $file )
0  'Licensed material - Property of IBM.'
1  'IBM(R) SDK, Java(TM) Technology Edition, Version 6'
2  'IBM(R) Runtime Environment, Java(TM) Technology Edition, Version 6'
3  ''
4  'Copyright Sun Microsystems Inc, 1992, 2008. All rights reserved.'
5  'Copyright IBM Corporation, 1998, 2009. All rights reserved.'
6  ''
7  'The Apache Software License, Version 1.1 and Version 2.0'
8  'Copyright 1999-2007 The Apache Software Foundation. All rights reserved.'
9  ''
10  'Other copyright acknowledgements can be found in the Notices file.'
11  ''
12  'The Java technology is owned and exclusively licensed by Sun Microsystems Inc.'
13  'Java and all Java-based trademarks and logos are trademarks or registered'
14  'trademarks of Sun Microsystems Inc.  in the United States and other countries.'
15  ''
16  'US Govt Users Restricted Rights - Use duplication or disclosure'
17  'restricted by GSA ADP Schedule Contract with IBM Corp.'
DB<4> x @array2 = read_file( $file ) || die "Cannot read $file\n";

0  'Licensed material - Property of IBM.
IBM(R) SDK, Java(TM) Technology Edition, Version 6
IBM(R) Runtime Environment, Java(TM) Technology Edition, Version 6

Copyright Sun Microsystems Inc, 1992, 2008. All rights reserved.
Copyright IBM Corporation, 1998, 2009. All rights reserved.

The Apache Software License, Version 1.1 and Version 2.0
Copyright 1999-2007 The Apache Software Foundation. All rights reserved.

Other copyright acknowledgements can be found in the Notices file.

The Java technology is owned and exclusively licensed by Sun Microsystems Inc.
Java and all Java-based trademarks and logos are trademarks or registered
trademarks of Sun Microsystems Inc.  in the United States and other countries.

US Govt Users Restricted Rights - Use duplication or disclosure
restricted by GSA ADP Schedule Contract with IBM Corp.
'

なぜ|| ダイが違いを生む?これは、File::Slurp の質問ではなく、Perl の優先順位に関する質問のような気がします。File::Slurp モジュールを調べたところ、問題があれば鳴くように設定されているようです。そのため、適切な方法は File::Slurp が鳴るようにすることだと思います。今、なぜこれらの違いが見られたのか不思議です。

4

3 に答える 3

9

ブール演算子or演算子||は、代入演算子よりも厳密にバインドされ、関数呼び出しをスカラー コンテキストに配置します。

my @array = read_file( $file ) || die "Cannot read $file\n";

つまり、ファイルを読み取ろうとし、ファイルの連結または "return"dieを の最初の要素として返します@array。ファイルを読み取り、スカラー値ではありますが真の値を返したので、あなたは死ぬことはありません。

標準的な使用法は、次のようなステートメントまたは演算子 ( ) です。or

my @array = read_file( $file ) or die "Cannot read $file\n";

これは、リスト コンテキストで代入を試行し@array、割り当てられたリストをスカラー コンテキストで評価して、配列内の項目数を取得します。したがって、最初に配列を割り当てると、配列にエントリがあるため、死ぬことはありません。

2 番目の形式は、最初に割り当てが行われるため、 "return" from dietoを割り当てようとしません。そのため、ファイルの行を保持するか、空の配列になります。@array@array

のドキュメントにFile::Slurp read_fileは次のように記載されていることに注意してください。

リスト コンテキストでは、行のリストを返します ($/ の現在の値をセパレータとして使用し、'' に設定されている場合は段落モードのサポートを含みます)。スカラー コンテキストでは、ファイル全体を単一のスカラーとして返します。[イタリック鉱山]

そして、次の例を示します。

    my $text = read_file( 'filename' ) ;
    my @lines = read_file( 'filename' ) ;

しかし、これらは最も単純なケースであり、コンテキストの最も基本的な表現です。特定の型の変数に割り当てても@lines、周囲のコードに関係なくリスト コンテキストで割り当てられるとは限りません。

于 2010-06-02T14:02:42.817 に答える
6

||演算子は、左側のオペランドをブール (スカラー) コンテキストに置きます。

C スタイルの論理和

Binary||は、短絡論理 OR 演算を実行します。つまり、左のオペランドが true の場合、右のオペランドは評価されません。スカラーまたはリスト コンテキストは、評価される場合、右側のオペランドまで伝播します。

これを経験的に発見することもできます。

#! /usr/bin/perl

sub lhs {
  my $ctx = wantarray;
  if (defined $ctx) {
    if ($ctx) { "list" }
    else      { "scalar" }
  }
  else { "void" }
}

print lhs || 0, "\n";

出力:

$ ./or-ctx.pl
スカラー

プログラムを修正するには、わずかに変更できます。

my @array = eval { read_file("/etc/issue") };
die unless @array;

$@これは、エラー メッセージ ( の後の特殊変数に格納されるeval)に追加read_fileする場合にのみ必要ですdie

于 2010-06-02T13:49:48.883 に答える
4

あなたの質問はすでに回答されています。補足として、最初に、 と はフロー制御ステートメントにより適していることに注意してorくださいand。しかし、もっと重要なのは、以下のチェック

 my @array = read_file( $file ) || die "Cannot read $file\n";

は完全に不要です。デフォルトでは、File::Slurp::read_file croakはエラー時に:

err_mode

このオプションを使用して、エラーが発生したときの read_file の動作を制御できます。このオプションのデフォルトは「croak」です。「carp」または「quiet」に設定して、エラー処理を行わないようにすることができます。

于 2010-06-02T15:41:14.963 に答える