メモ
RubyにないCrystalの特徴のひとつであるメソッドのオーバーロード。
当然,initialize
メソッドもオーバーロード可能。
普通に initialize
メソッド内で別形式の initialize
メソッドを呼べば良いっぽい。
someclass.cr
class SomeClass
def initialize(int_value : Int)
@value = int_value
end
def initialize(string_value : String)
initialize(string_value.to_i)
end
end
p SomeClass.new(1)
p SomeClass.new("2")
$ crystal someclass.cr
#<SomeClass:0x100f34fe0 @value=1>
#<SomeClass:0x100f34fd0 @value=2>
これくらいの例だったら,引数の型を指定せずにおいて initialize
内で to_i
すれば良い気もするけれど,Rubyの IPAddr が new
にアドレス表記の文字列と数値の両方を受けられるみたいな例だと,1つの initialize
の中で処理を条件分岐させるより,それぞれ別の initialize
に処理を分割したほうがソースがスッキリしそう。
注意
まかり間違って同じ形式の initialize
を呼び出してしまうと,実行時に怒られる(buildは通る)ので注意。
someclass2.cr
class SomeClass
def initialize(int_value : Int)
@value = int_value
end
def initialize(string_value : String)
initialize(string_value) # <- initialize(String)
end
end
p SomeClass.new(1)
p SomeClass.new("2")
インタプリタ実行
$ crystal someclass2.cr
#<SomeClass:0x109fa4fe0 @value=1>
Program terminated abnormally with error code: 11
コンパイル実行
$ crystal build someclass2.cr
$ ./someclass2
#<SomeClass:0x10aa99fe0 @value=1>
Segmentation fault: 11