2011-04-22 91 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

相關問題