Crystalでnot nilなgetterを定義する

環境

$ crystal version
Crystal 0.15.0 [0f62400] (Fri Apr  1 16:59:50 UTC 2016)
$ crenv --version
crenv 1.0.0-7-g578eb0a

問題点

適当に getterproperty を生やしてるとNot Nilであることをコンパイラが検知できなくて困る

対応策

  • getter に型定義を書いておく
  • 型推論を活かしつつ getter! あるいは property! を使う
  • initialize 内で インスタンス変数 @fuga に値を入れる

楽に書きたい派なので getter! を好んで使っている

確認

hkdnet/crystal-tips

$ crystal run src/tips/nillable_property.cr
Error in ./src/tips/nillable_property.cr:10: undefined method 'split' for Nil (compile-time type is String?)

puts h.fuga.split("")
            ^~~~~

================================================================================

Nil trace:

  macro getter (in /Users/username/.anyenv/envs/crenv/versions/0.15.0/src/object.cr:221):4

          def fuga
              ^~~~

  macro getter (in /Users/username/.anyenv/envs/crenv/versions/0.15.0/src/object.cr:221):5

            @fuga
            ^~~~~

================================================================================

Error: instance variable '@fuga' of Hoge was not initialized in all of the 'initialize' methods, rendering it nilable

Specifically in this one:

  ./src/tips/nillable_property.cr:4

      def initialize
          ^~~~~~~~~~
$ crystal run src/tips/not_nil_property.cr
["p", "i", "y", "o"]

最近ずっとCrystal書いてるので思い出しながら適当にtips集を書いておこうかと思いました。
その第一弾です。続くといいな。