2013-01-09 24 views
8

まず、私はC、Java、Pythonの背景から来ています。最近、私は新しい仕事のためにPerlを学び始めました。私は'0'(0文字列)が間違っているのを知りました。なぜPerlでは '0'が間違っていますか?

この特定の動作が、Perlがファイルを読み取るためにオペレータ<>を持っていなければならない理由であることを読んだことがあります。しかし、私はPerlが成熟した言語であることも知っています。私はこの動作には長い時間前に修正されていたはずの使用があると推測しています。

したがって、どの場合に'0' = falseが有用でしょうか?

+2

言語はアプリケーションプログラムと似ていません。ストリング "0"の偽りが確立されると、機能していないプログラムの数を壊す危険なしに変更することはできません。 –

+1

「0でも間違った」トリックもあります。 –

答えて

9

Perlには明示的な型定義がなく、その型の解釈はコンテキスト依存性が高い。たとえば:

$a = "2b"; 
$b = "3a"; 
$c = $a + $b; 
print $c; 

は一方5.

...

$a = "b2"; 
$b = "3a"; 
$c = $a + $b; 
print $c; 

利回り3を生成します。

と...

$a = "b2"; 
$b = "3a"; 
$c = $a.$b; 
print $c; 

、あなたがそれを使用するまで、 " '0'(文字列)"、文字列、または数、またはブール値ではありませんので、b23a

をもたらし、そしてその使用によって決定されるものであれば、どれでもかまいません。タイプは、操作しようとするまで決定されません。そして、Perlはコンテキストを評価してあなたの意図を遂行し、それに応じて行動します。これはフィーチャーであり、Perlには多くの方法があります。もちろん、混乱を招くようなコードもたくさんありますが、1ライナー、難読化、Perlゴルフには優れています。

7

Perl steals は、C、awk、Bourneシェルなど多数の言語の機能を継承しています。

Cでは、0の値はすべてfalseで、0以外の値はすべてtrueです。 Perlは同じセマンティクスを使用しています。

Cが行うよりもスカラーやブール値の文脈でPerlが使うことができる事実、特に文字列は、Perlが複数のの値を持つことを意味します。

整数を0にすることは、Cプログラマにとって理にかなっています。空の文字列を""にすることも意味があります。 Perlは同じスカラーを数値または文字列として扱うことができるので、文字列"0"をfalseにすることはほとんど不可避でした。例えば

:Perlは他の言語から非常に多くの機能を借りずにゼロから設計されていた場合

$x = 2; 
$x -= 2; 
print "x = $x\n"; # prints "x = 0" 
if ($x) { 
    print "A C programmer would be surprised to see this\n"; 
} 

$x = ""; 
$x .= chr(48); 
# Now $x eq "0", a string value that was built without reference to 
# the number zero -- but it's nearly the same thing as the number 0. 
print "\$x = $x\n"; # pritn "x = 0" 
if ($x) { 
    print "A C programmer would be equally surprised to see this\n"; 
} 

、それというと、それらを一緒にグループ化するよりも、文字列と数字の間に強い区別を、作ったかもしれませんスカラー。そのような仮説的なPerlのような言語を考えれば、おそらく空の文字列と数字0は偽になりますが、文字列"0"が真となります。数字0から文字列"0"に変換する必要があります。

しかし、Perlはそのままです。

11

これは、<>と何か関係があります。私はその主張がどこから来るのか想像できません。

ほとんどの場合、perlは数値形式と文字列形式で格納された数値を区別しないため、 '0'はfalseです。ブール値テストでは、このグレインに対して実行されます。

「0」が真である言語(Python、Javascript?)では、「偽」であることが奇妙であることがわかります。なぜ1つの文字列の例外を作成しますが、もう一方の文字列は例外にしませんか

+5

私はOPが 'while(<>){...}'で暗黙の 'defined'テストを話していると思います。これは、 '<>'から読むと、読み込み文字列が '' 0 ''のときにループが終了しないようにするためです。それを明示的に見るために 'perl -MO = Deparse -E 'を試してみてください(<>){say}。 –

+1

@JoelBerger: 'while(<>)'は入力の最後の行に '0' *という文字だけが含まれている場合にのみ' $ _'を '' 0 "'に設定することに注意してください。それ以外の場合、 '0'は' $ _'を '' 0 \ n "'に設定します。これは奇妙なコーナーケースですが、while(<>)が正しく処理できなかった場合は、扱いにくいでしょう。 –

+1

これは '<>'よりも特殊なケースです。 'while(glob" {0,1} ")'ここで 'for(File :: Temp-> newdir){mkdir" $ _/0 "; opendir DH、$ _; readdir * DH} ' – ysth

2

Perlには、「undef」という文字列が含まれています。"0"、空の文字列、コンテキストに応じて空の文字列または空のリストに変換する特別なブール値、およびbooleanコンテキストに対してオーバーロードされます。

これらのほとんど(undef、ゼロ、空の文字列、特別な値、オブジェクト)は実際には非常に便利です。文字列"0"がfalseであるということは、perlがスカラーと偽を実装する方法に由来します。スカラーには、文字列部分と数値部分の両方が含まれています。判定するために、値がfalseの場合、文字列部分はの最初のと照合されます。なぜこれが必要ですか?

my $false_ish = 0; # the scalar contains only a number 
'' . $false_ish; # force stringy context. the scalar now contains stringy portion. 
if ($false_ish) { ... } # string portion is consulted first... 

これがなければ、数字ゼロは文字列が必要な場所で使用するとその偽りを失います。一方、これにより、"0 but true"、数字がゼロの真の文字列、ゼロの科学記法である"0E0"が可能になりますが、真と評価されます。

7

内部記憶形式は、理想的にはPerlでは重要ではありません。 IV、UV、NV、PVなどに格納されているかどうかにかかわらず、ゼロは0です。

実際、可能なので、Perlは値が格納されている形式を変更してあなたを驚かせるかもしれません。文字列0が本当だった場合は、「真の」印刷し、次の

$x = 0; 
print("$x\n"); 
if ($x) { 
    print("true\n"); 
} else { 
    print("false\n"); 
} 
1

0は、同様に、Cにはfalseに相当する - それはおそらく、0の固有のネクタイに、いくつかの「レガシー」のプログラミング言語ではfalseに相当しますバイナリと回路であり、0は「無償」を意味します。

いずれの場合でも、新しい言語は、以前は言語の振る舞いや解釈を継承していることがあります。 0のバイナリの意味は "無償"または "それは電荷があるということは間違いです"という言葉は、ハイレベルなプログラミング言語から抽象化されてからずっと古くなっていますが、最も近代的なプログラミング言語でさえ意味論の謎がまだ残っています。

また、私の知る限り、それは<とは関係ありません - あなたはそれをどこで読んだのですか?

+0

私はこれがポイントを欠いていると思います。 GoldenDは文字列 "0"を具体的に話しており、なぜPerlがそれを0の整数と同じように解釈しているのですか?HeWasはこれについて上にコメントしています。同じ操作を別の言語と比較する。 Pythonでは: "0" == TrueはFalseに評価されます。 – mmoore

関連する問題