5

处理由于传递了无效的初始化参数而导致对象无法初始化的情况的 ruby​​ 最佳实践是什么?

我意识到在 ruby​​ 中,鸭子类型意味着我们不应该过度关注变量/参数的类型,而是关注它们的行为方式。但是,我在 MacRuby 中工作,它通过 Cocoa Objective-C API 桥接,一些 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​​ 坚持总是返回一个活动实例。

我读过的所有内容都表明,在 ruby​​ 中类型检查非常不受欢迎,但在 MacRuby 的情况下,我可能不得不破例。这是在 ruby​​ 中很好地使用异常还是有更优雅的解决方案?我是红宝石的菜鸟,所以假设我从错误的角度处理问题。

4

1 回答 1

1

TypeError如果无法进行转换,我会尝试转换参数并引发 a :

遇到不属于预期类型的​​对象时引发。

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

引发异常:

TypeError: can't convert String into Integer

Ruby 核心和标准库可以做到这一点,所以你也没有理由不能这样做。当你做一些你不应该做的事情(调用不受支持的方法,调用带有错误数量的参数的方法,......)时,Ruby 核心会引发异常,因此抛出 aTypeError是有意义的。而且,如果TypeError不太合适,总有ArgumentError.

在您的特定情况下,如果他们没有给NSURLto_s一个. 我不知道如何使用 MacRuby 或相应的 Mac API,所以我在猜测这种特定情况下的明智行为,但我认为“转换或引发异常”的想法是合理且明智的。NSURLNSURL

当然,您也应该在 API 文档中记录您将要使用的行为。

于 2011-05-14T03:26:53.180 回答