無効な初期化引数が渡されたためにオブジェクトの初期化に失敗する状況を処理するための Ruby のベスト プラクティスは何ですか?
ルビーでは、ダックタイピングとは、変数/パラメーターの型に過度に関心を持つべきではなく、それらがどのように動作するかに関心を持つべきであることを意味することを認識しています。ただし、私は Cocoa Objective-C API を介してブリッジされた MacRuby で作業しており、一部の Cocoa メソッドは型付きパラメーターを想定しています。
たとえば、Objective-C API を呼び出す ruby クラスがあり、それに NSURL クラスのオブジェクトを渡す必要があります。次のようになります。
class Alpha
attr_accessor :model
def initialize(hopefully_a_NSURL)
# bridged from Objective-C API
@model=NSManagedObjectModel.alloc.initWithContentsOfURL(hopefully_a_NSURL)
end # initialize
end
...そして私はそれを次のように呼びます:
#bridged from Objective-C API
u=NSURL.fileURLWithPath(p)
a=Alpha.new(u)
puts "a=#{a.model}" # => a=#<NSManagedObjectModel:0x2004970e0
>
...うまく機能します。
ただし、私が失敗した場合:
a=Alpha.new("Whoops, a string not a NSURL" )
... Objective-C API の深みから来るエラーで乱雑に爆発します。
もちろん、ブリッジされたオブジェクトに到達するための不正なパラメーターを防ぐテストを入れることもできます。
class Alpha
attr_accessor :model
def initialize(hopefully_a_NSURL)
if hopefully_a_NSURL.class==NSURL
@model=NSManagedObjectModel.alloc.initWithContentsOfURL(hopefully_a_NSURL)
end
end # initialize
end
u=NSURL.fileURLWithPath(p)
a=Alpha.new("")
puts "a=#{a}" # => a=#<Alpha:0x200399160>
...しかし、まだライブ インスタンスが返されます。初期化から nil を返そうとさえしましたが、ルビーは常にライブインスタンスを返すことを主張しているようです。
私が読んだものはすべて、Ruby では型チェックが非常に嫌われていると言っていますが、おそらく MacRuby の場合は例外を設ける必要があるでしょう。これは ruby の例外の有効な使い方でしょうか、それとももっと洗練された解決策がありますか? 私はルビーの初心者なので、間違った視点から問題に取り組んでいると思います。