メモ
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