@yukikimoto さんのツイートを発端に色々調べることになった件をまとめますが、このまとめ自体へ方々からツッコミが入ると思います。
編集リクエスト、コメント大歓迎。皆さんの知識を借りて有用な記事にしたいと思います。
#Perlにおける真値とは?
代表的な値として1
が挙げられますが、これは正確ではありません。Perlでは、__偽値でないあらゆる値が真値__です。偽値の定義が複雑なのでもはやこう表現するほかありません。
#Perlにおける偽値とは?
他言語との比較でよくある誤解としてfalse
という文字列があげられますが、これは真値です。false
という関数も(作らなければ)ありません。
とりあえず列挙。
-
0
と'0'
や"0"
- 空の文字列(
''
や""
) - 空のリストや配列'
()
' undef
- 「真偽値コンテキストでの偽値」としか言い表せれない値1(
!1
など)
次に、一つ一つ見ていきましょう。
##0
と'0'
や"0"
数学的に0
と等価な値、および計算結果は数値型である限り偽です。2
例:0.00
, 0x0
,0e0
, 3-2-1
, sin(0)
など
ただし、これらが文字列だった場合、'0'
や"0"
を除いて真となります。
##空の文字列
length
が0
になる文字列は偽です。''
,""
しかないはずです。
##空のリスト
$#array名
が-1
になるリストや配列は偽です。()
しかないはずです。
機序について詳しい記事はこちら
なお、空のハッシュは空の配列と区別がつかない3ので省略します。
##undef
undef
は文字列コンテキスト、リストコンテキストで空になり、数値コンテキストで0
になるので結果的に常に偽です。が、use warnings
支配下では警告の原因になるので使わない方が良いかもしれないですね。
##真偽値コンテキストでの偽値
例えば、__!
で反転した任意の真値は偽__です。
他には比較演算子の結果が偽だった時の返値などが該当します。
私はこれがundef
と等価だと勘違いをしていましたが、仕様上は別とのこと。4
###どの辺がundef
と違うの?
-
defined
で真 - なので、
use warnings
支配下で警告が出ない。
#まとめ
Perlが直感的に正しいように設計されてるからこんなこと考えずに真偽判定できるけど、詳しく調べると深かった。積極的に区別して使いたいですね。
ひとことで言うと、文字列に変換したときに''か'0'にならなければ真です。
akajiroさんのツイートより
なるほどね。
-
内部的に違うかもしれないが、Perlでの表現はともに
()
である ↩