3

On http://novosial.org/perl/one-liner/ I found the following two one-liners. The outputs are different because the unless statement is different from if ! ( due to the associativity and precedence rules ).

cat file:  
foo  



bar  
perl -ne 'print unless /^$/../^$/' file  
foo  
bar  
perl -ne 'print if ! /^$/../^$/' file  
foo  

bar  

How does the different behavior of the if !-statement make the second one-liner output one blank line?

4

3 に答える 3

6

リンクされた記事が言うように、それは結合性と優先順位の問題です...

print unless /^$/../^$/と同等ですprint if !(/^$/../^$/)

print if ! /^$/../^$/と同等ですprint if (!/^$/)../^$/

1 つ目は範囲式を否定し、2 つ目は範囲の開始条件を否定しますが、範囲自体は否定しないことに注意してください。

于 2010-03-07T10:47:15.697 に答える
4

答えは、私見ですがif !、Perl にはステートメントがないということです。ifステートメントがあり、!演算子があります。!演算子は にバインドしませifん。それはその引数に基づいて動作します。これらの用語で考え始めると、あなたの人生は楽になります。

だから、あなたの場合、あなたは持っています、

do_something() unless something;

do_something() if something-else;

通常は見えない括弧を入れましょう:

do_something() unless ( something );

do_something() if ( something-else );

この場合、something-elseその条件の真偽値が の真偽と等しくなるように記述しようとしましたが、演算子が厳密にバインドさsomethingれるという事実を考慮に入れていませんでした。!

だからこそあるのですnot

試す

perl -ne 'print if not /^$/../^$/' file  

notperldoc perlopを参照してください:

単項式notは、式の論理否定を右側に返します。!優先順位が非常に低いことを除いて、これは同等です。

于 2010-03-07T13:12:06.707 に答える
1

範囲テストは、第 2 オペランドが true になるまで true を返します。その後、次の呼び出しで false を返します。

このスニペットは、範囲演算子が何を返すかを示しています

perl -ne "$x= ( ! /^$/../^$/ ) ; print qq/$x : $_/" range_test.TXT

生産する

1 : foo
2E0 :
 :
 :
1 : bar

したがって、最初の空白行は true 応答を生成し、次の空白行は false を生成します

于 2010-03-07T10:59:32.690 に答える