これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の12日目の記事です。
Crystal で Ruby と同じような感覚でインスタンス変数を使うと nil だと怒られることがあります。
class Hoge def hoge @hoge = "abc" @hoge.size end end Hoge.new.hoge
% crystal hoge.cr Error in ./hoge.cr:8: instantiating 'Hoge#hoge()' Hoge.new.hoge ^~~~ in ./hoge.cr:4: undefined method 'size' for Nil (compile-time type is String?) @hoge.size ^~~~ ================================================================================ Error: instance variable '@hoge' of Hoge was not initialized in all of the 'initialize' methods, rendering it nilable Specifically in these ones:
initialize メソッドで初期化されていないインスタンス変数は、暗黙的に nil で初期化されるためです。 つまり上の例は、次と同じです。
class Hoge def initialize @hoge = nil end def hoge @hoge = "abc" @hoge.size end end
@hoge は Nil または String のどちらの値にもなりうるので、Nil にない size メソッドを使うとエラーになります。
エラーにならないようにするには initialize で文字列として初期化してしまえばよいです。
class Hoge def initialize @hoge = "" end def hoge @hoge = "abc" @hoge.size end end
または明に String として宣言することもできます。
class Hoge def initialize @hoge :: String end def hoge @hoge = "abc" @hoge.size end end
追記 2016-05-14
最後の例は 0.12 から使えなくなりました。