Rubyでnil安全？


[null安全でない言語は、もはやレガシー言語だ](http://qiita.com/koher/items/e4835bd429b88809ab33)を読んだ多くのRubyistは衝撃を受けたことだろう。そう、Rubyはオワコンなのだ。まだ始まってすらいないのに既に終わったのだ。クロムが少々混ざった程度の酸化アルミニウムよりも二酸化ケイ素の時代なのだ。まぁ霊薬も捨てがたいが。

だがし、かし。Rubyのポテンシャルはそんなものではないはずである。そう、たったひとつ魔法の呪文、次の一行を先頭に書けば、我らは`NoMethodError`の呪縛から解放されるのだ。

```rb:魔法の呪文
def nil.method_missing(*_);nil;end
```

もうこれで、忌々しき``NoMethodError: undefined method `なんか' for nil:NilClass``を見ることは無いだろう。我々は`NoMethodError`を封印に成功し、より高次元のレベルに至ったのだ！

---

さて、よくわからない文章から始まりましたが、今回の**ポエム**のテーマはRubyで _nil安全_ です。_null安全_ ではありません。だって、Rubyには`null`がないんだもん。

_null安全_ のメリットに、`NullPointerException`等の変数や戻り値が`null`であったが故のエラーを防げるというのがありました。Javaはヌルポばかりで困るというアレです。Rubyも他人事ではありません。変数や戻り値が`nil`だったとき、アヒルのように鳴くことはできないので、やはりエラーになります。ただ、`null`とは違い`nil`も**一つオブジェクト**です。なので、出るエラーは、想定していた型が間違っていて、呼び出すべきメソッドがなかったことを意味する`NoMethodError`になります。

そう、この**魔法の呪文**は`nil`に対する`NoMethodError`をなくす素晴らしいものです。もし、想定外で`nil`だったとしても、`nil`が返ってくるだけです。メソッドチェーンで繋いでも、`nil`からまた`nil`が返ってきて何のエラーも起きません。すごいと思いませんか？

気付いた人がいると思いますが、nilが元々持っているメソッド以外について全て`&.`にしているような物です。考えようによっては、全てが常にMaybeモナドに包まれている、nullableになっている、とも言えます。[nilable](https://rubygems.org/gems/nilable)なんてgemもあるんですけど、言ってしまえば、強制的に常にこのgemで言う`Nilable(...)`っていると言うことです。

Rubyの世界ではもともと全部nilableです。そもそもnilableじゃない物なんて無かったのです。`nil`から導かれる物はが`nil`になる、そう、これは_null安全_の仕組みと同じです。となると…うん、そう、まさしくこれは _null安全_ もとい _nil安全_ と言ってもいいのではないでしょうか？

ということで、Rubyが _null安全_ じゃない、レガシーだ、オワコンだ、と言う人には、この魔法の呪文で、Rubyは _nil安全_ になる！と言い張りましょう。

**勝ったな。**

---

では、オチです。

さて、この方法、副作用があるんじゃ無いか？という前に、意味があるのか？を問わなければなりません。私が言い始めたのに何なのですが、あまり意味がないと思っています。なぜなら、魔法の呪文で _nil安全_ にはなりましたが、違う型であった場合は依然として`NoMethodError`が発生するからです。

`x.quack`と書いたとき、私は`x`が`Duck`クラス、または、`Duck`クラスっぽい何かのインスタンス(**きっとそれは`Duck`である**[^1])を期待しています。そして、きっと`"quack"`のような物が返ってくることを期待しています。魔法の呪文は、`nil`であったら`nil`が返ってくるので、何も処理できないで終わりました。それはいいかもしれませんが、これがもし別の何かだったら？そう、エラーになります。犬も猫も`quack`することはできないのです。

[^1]: If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.

Rubyにおいて動的型付けであるが故の特徴の一つが、ダッグ・タイピングができると言うことです。先ほどの`x.quack`は`ToyDuck`クラスならきっとうまくいくでしょう。戻り値は`"quack"`からややずれた物かも知れませんが、それは些細な問題です。実際に鳴いて貰うその時になって初めて、それがアヒルなのかを判断するため、それまでは`x`については何でもいいかのように扱えるのです。実行時に`x`がアヒルになってさえいればいいのです。しかし、これには矛盾があります。私達は`x.quack`と書く時、やはり`x`がアヒルであることを常に期待します。期待していながらも、そのときまではわからない。ダッグ・タイピングの限界はここにあると思います。

つまり、`x`がアヒルであることを期待するのであれば、やはり、`x`がアヒルであると言うことを、実行時ではなく、期待を込めているその時にすぐさま知りたいのです。必要なのはCrystalのような静的型付けかPythonとmypyのような型ヒントと静的型チェックなのです。現在のRubyにはそれが欠けています。実行してみたらアヒルじゃ無かったと言って、`NoMethodError`が発生してしまう可能性があります。静的な型チェックがなければ、`nil`の`NoMethodError`のみを解決しても何もならないと言うことです。そんな状態で _nil安全_ なんて言っても餡だけの饅頭みたいな物です。[^2]

[^2]: 他にもこの方法には欠点があります。一つはnilableでないということが書けないこと。もう一つはコメントでご指摘頂いているとおり、メソッド側が内部で行う型チェックでのTypeErrorが防げないこと。どちらも静的型付けや型ヒント+静的型チェックが無ければ、事前チェックは不可能であり、現在のRubyの仕様では実現はできないと思われます。

餡だけの饅頭…もうそれってただの餡なんじゃ…って思うかも知れませんが、逆に言うと _null安全_ じゃない型チェックは餡がない饅頭と言うことです。皮だけの饅頭…そりゃおいしいわけがありませんね。静的型付けや型ヒント+静的型チェックには _null安全_ があって初めておいしい饅頭になり得るのです。もし、_null安全_ が保証できないのであれば、Rubyのように初めから全部安全じゃない方がいいとすら私は思います。どうせ、静的に全てをチェックできないのであれば、煩わしい型など書かない方がいいのです。常に動的に移り変わる可能性を意識し、テストを十分にした方がいいのです。

将来、たぶんRuby3の時に、何かしらの型チェックシステムが新たに導入されると言われています。そのとき、_null安全_ ならぬ _nil安全_ がきっと導入されると期待しています。しかし、ダッグ・タイピングを捨てずにそれができるのか、そもそもダッグ・タイピングとは何だったのかを再度考えるきっかけになるのではないでしょうか。[^3]

[^3]: mypyが成功するか否かに一番注目しているのは、Rubyの開発者達のような気がします。

とにかくそれまでは、Rubyは _null安全_ でははないといちゃもんを付ける人達には、そももそRubyは型チェックすらできないから**それ以前の問題だ**、と答えたいと思います。次元が違うと言うより、異世界の話をしていることです。