はじめに
Crystalでコードを書く際には、オブジェクトが nilable かどうかに強い関心を払う必要があります。そんなときに、手っ取り早く nilable ではないということを示すために使える書き方が not_nil! です。
not_nil! の実装は?
まずObjectクラスに、何もしないメソッド not_nil! を実装します。
class Object
def not_nil!(message)
self
end
end
次に、Nil 構造体に、例外を発生させる Nil#not_nil! を実装します。
オーバーロード を使っています。
struct Nil
def not_nil!(message = nil) : NoReturn
if message
raise NilAssertionError.new(message)
else
raise NilAssertionError.new
end
end
end
言われてみると、あたりまえの実装なのですが、その手があったか!というシンプルさですね。
Crystalの魅力が伝わる良い例だと思って感動したのでQiitaにメモしました。
この記事は以上です。
Crystalの慣習では、not_nil! よりも、nilable ではないことが確定する新たな変数に代入する書き方が推奨されます。
# Crystal で慣習的に推奨される書き方
if a_is_not_nil = a_nilable
method_that_dose_not_accept_nil(a)
end
# もしくは明確にエラーを発生させる
a_is_not_nil = a_nilable || raise "a is nil"
しかし、スクリプトや急いでCrystalを書く場合に not_nil! は頻用されます。清書の段階で取り除けばOKだと思っています。