2011-04-22 132 views
3

我写了一个Ruby库(Rails中偶然使用)一些代码,提出抛出一个RuntimeError有点像如下:NoMethodError:未定义的方法`RuntimeError”

class MyClass 
    def initialize(opts = {}) 
    # do stuff 
    thing = opts[:thing] 
    raise RuntimeError "must have a thing!" unless thing.present? && thing.is_a?(Thing) 
    # more stuff 
    end 
end 

,当我跑我的全新rspec的规格在它,它看起来有点像:

it "should raise an error if we don't pass a thing" do 
    lambda { 
    my_class = MyClass.new(:thing => nil) 
    }.should raise_exception(RuntimeError) 
end 

我一直得到一些奇怪:

expected RuntimeError, got 
#<NoMethodError: undefined method `RuntimeError' for #<MyClass:0xb5acbf9c>> 

回答

11

您可以ALRE ady已经发现了这个问题......啊,单字bug,doncha爱em?

这是它。

WRONG:

raise RuntimeError "must have a thing!" unless thing.present? && thing.is_a?(Thing) 

RIGHT:

raise RuntimeError, "must have a thing!" unless thing.present? && thing.is_a?(Thing) 

当然,你也可以先走一步,完全离开了RuntimeError:

raise "must have a thing!" unless thing.present? && thing.is_a?(Thing) 

,因为它是默认反正...

5

你缺少一个逗号:

raise RuntimeError, "must have a thing!" unless thing.present? && thing.is_a?(Thing) 
       ^
+0

啊 - 你回答之前,我有我的答案了:)这实际上是一个“解决前”的问题......我想别人去同样的问题,并可能想要的答案太... – 2011-04-22 15:50:32

1

我想补充一点点的解释:在Ruby中,有变量引用和消息发送之间的歧义。

foo 
Foo 

要么意味着“间接引用(或Foo)命名foo变量” “用空的参数列表,默认接收器发送消息:foo(或:Foo)”。

这种不确定性如下解析:

  1. 如果foo开始用小写字母,它被认为是一个消息发送,除非解析器见过的分配foo,在这种情况下,它被视为一个变量取消引用。 (请注意,赋值只需要解析,不执行; if false then foo = nil end是完美的罚款)
  2. 如果Foo开始以一个大写字母,它是作为一个变量处理(或相当恒定)解引用,除非你传递一个参数,列表(甚至是空的列表),在这种情况下,它被视为发送消息。

在这种情况下,RuntimeError被视为消息发送,因为它有一个参数列表:"must have a thing!"。当然,这是因为Ruby的另一个特点,即它允许你在参数列表中舍去括号,只要它是明确的。

督察:整个事情大致解释为

self.RuntimeError("must have a thing!") 
+0

你是否认真,如果错误:foo = nil'可以覆盖我的调用本地方法,如果它btw是一个类? – alanjds 2012-06-15 21:58:08

相关问题