🙅
Falsy について
Falsy
- 偽とみなされる値のこと。
- プログラミング言語ではいわゆる boolean 型の false 以外の値でも、真偽判定の時に false 相当(=偽)と判定される値があることがある。
- いわゆる boolean 型への暗黙の型変換の一種と考えてよい。
- 本当のところプログラミング言語によりどう処理されているかは言語仕様を見ないとはっきりしない。
- これはコードを書きやすくするための糖衣構文の一種になっている。
- プログラミング言語の設計思想によるため、善し悪しは明確ではない。
- Falsy の反対は Truthy
- Falsy でもなければ Truthy でもないという値は通常存在しない。(排中律)
- SQL では TRUE, FALSE, NULL(unknown) の3値論理になっているので要注意。
- Falsy, Truthy の概念は、バグの要因になりやすい。
- Falsy と Truthy の範囲が誤解されているため、バグの要因になりやすい。
- 例えば、0 が Falsy、0 以外が Truthy であるにも関わらず、1 が Truthy と誤認しているコードが後を絶たない。
- C言語/C++では、真偽値を0と1に変換する仕様になっていて、真偽判定の時には、0か非0かを判定している。このため、1で判定しても大丈夫なことがあり、話がややこしくなっている。
- 例えば、空文字列または"0"が Falsy であるにも関わらず、空文字列のみが Falsy と誤認しているコードが後を絶たない。
- 例えば、Map.get のようなもので値を取得した時に、存在しないことを示す値(例えば undefined)と、読み出した値そのもの(例えば null)が両方 Falsy であることがある。
- 例えば、0 が Falsy、0 以外が Truthy であるにも関わらず、1 が Truthy と誤認しているコードが後を絶たない。
- プログラミング言語により異なっているため、バグの要因になりやすい。
- 例えば、JavaScript, Python では "0" は Truthy、PHP, Perl では "0" は Falsy
- 何も考えずにコードを見たまま移植するとバグとなる。
- 別の言語を習熟済みのプログラマがうっかり書き間違える事故が多発する。
- Falsy と Truthy の範囲が誤解されているため、バグの要因になりやすい。
- このため、明示的な型変換を要求するのが最近の主流になりつつある。
Falsy の概念を持たない代表的な言語
- C#
- D
- Java
- Rust
Falsy の概念がある代表的な言語
- false 以外に false として扱われる値があるならば、ここに入れる。
C言語/C++
値 | 意味 |
---|---|
0 | 数値の0 |
NULL, ((void*)0) | NULLポインタ |
false | false (C99~) |
- NULL ポインタの内部表現は 0 の内部表現と等しいわけではない。0 と比較するべきではない。
- C FAQ 5章 ヌルポインター http://www.kouno.jp/home/c_faq/c5.html
JavaScript
値 | 意味 |
---|---|
false | false プリミティブ値 |
0 | 数値の0 |
-0 | 数値のマイナス0 |
"" | 空文字列(長さ0の文字列) |
null | null ポインタ |
undefined | undefined プリミティブ値 |
NaN | 非数 |
PHP
- https://www.php.net/manual/ja/types.comparisons.php
- 条件式として使われる場合(= boolean 型への変換をした場合)
値 | 意味 |
---|---|
FALSE | FALSE プリミティブ値 |
0 | 数値の0 |
"" | 空文字列(長さ0の文字列) |
"0" | 文字列での"0" (1文字の"0"の時のみ偽) |
array(), [] | 長さ0の配列 |
null | null プリミティブ値 |
Ruby
- Ruby にはいわゆる boolean 型はなく、TrueClass と FalseClass がある。評価すると TrueClass は真を返し、FalseClass は偽を返す。
- NilClass も偽を返す。
- FalseClass と NilClass 以外のオブジェクトは評価するとすべて真を返す。
値 | 意味 |
---|---|
false | false (FalseClass のインスタンス) |
nil | nil (NilClass のインスタンス) (非存在を示す値) |
- https://docs.ruby-lang.org/ja/2.7.0/class/FalseClass.html
- https://docs.ruby-lang.org/ja/2.7.0/class/NilClass.html
Python
値 | 意味 |
---|---|
False | False プリミティブ値 |
None | None プリミティブ値 (非存在を示すポインタの一種) |
0, 0.0, 0j, Decimal(0), Fraction(0, 1) | 数値の0 (0と等しい値すべて) |
'', (), [], {}, set(), range(0) | 空のシーケンスまたはコレクション |
Perl
値 | 意味 |
---|---|
0 | 数値の0 (0と等しい値すべて) |
"" | 空文字列(長さ0の文字列) |
"0" | 文字列での"0" (1文字の"0"の時のみ偽) |
長さ0のリスト | |
要素数0のハッシュ | |
undef | 未定義値 |
未定義変数 |
- 文字列に変換したときに
''
(空文字列)または'0'
(文字列で数字1文字のゼロ)に変換されるなら偽、というのが直感的な理解とのこと。
Discussion