5

無効な初期化引数が渡されたためにオブジェクトの初期化に失敗する状況を処理するための 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​​ の例外の有効な使い方でしょうか、それとももっと洗練された解決策がありますか? 私はルビーの初心者なので、間違った視点から問題に取り組んでいると思います。

4

1 に答える 1

1

引数を変換して、TypeError変換が不可能な場合はa を発生させます。

予期されたタイプではないオブジェクトに遭遇したときに発生します。

[1, 2, 3].first("two")

例外を発生させます:

TypeError: can't convert String into Integer

Ruby のコアと標準ライブラリがそれを行うので、あなたもできない理由はありません。Ruby コアは、想定されていないこと (サポートされていないメソッドを呼び出す、間違った数の引数でメソッドを呼び出すなど) を行うと例外を発生させるため、 a をスローするTypeErrorことは理にかなっています。TypeErrorが適切でない場合は、常に がありArgumentErrorます。

あなたの特定のケースでは、引数を に変換してから、その文字列を使用して をNSURLインスタンスto_s化しNSURLてくださいNSURL。MacRuby や対応する Mac API の使い方がわからないので、この特定のケースでの賢明な動作を推測していますが、「例外を変換または発生させる」という考えは健全で賢明だと思います。

もちろん、使用する動作についても API ドキュメントで文書化する必要があります。

于 2011-05-14T03:26:53.180 に答える