2013-02-13 99 views
1

我覺得我的問題最好由該IRB會議捕獲:看似矛盾

irb(main):001:0> require 'sinatra' 
=> true 
irb(main):002:0> method(:get) 
=> #<Method: Object(Sinatra::Delegator)#get> 
irb(main):003:0> methods.include?(:get) 
=> false 
irb(main):004:0> wtf? 
NoMethodError: undefined method `wtf?' for main:Object 
     from (irb):4 
     from C:/Ruby193/bin/irb:12:in `<main>' 
irb(main):005:0> 

我的問題,這是一個真正的紅寶石,而不是一個具體的西納特拉個問題,就是如何可以method(:get)返回的東西而methods是不包括:get在其返回的數組?

+0

您正在處理的是什麼ruby版本? – 2013-02-13 08:08:23

+0

我正在使用版本1.9.3 – Jonah 2013-02-13 08:14:55

回答

3

好的。這花有點撓頭的,但最終的答案在documentation of methods發現,其中說:

返回公衆的名單和保護obj的方法。這將包括obj的祖先可以訪問的所有方法。

然後你與西納特拉源結合起來:

module Delegator 
    def self.delegate(*methods) 
    methods.each do |method_name| 
     define_method(method_name) do |*args, &block| 
     ... 
     end 
     private method_name # <- here 
    end 
    end 

    delegate :get, :patch, :put, :post, :delete, :head, :options, ... 
end 

,我們可以看到的問題是什麼。然後解決方案變爲:

private_methods.include?(:get) 
=> true 
+0

@Jonah對我來說,這似乎是想法是這些方法決不會從其他任何地方調用,而是直接從Sinatra應用程序類或全局範圍內調用。你永遠不想(或應該)用明確的接收者來調用它們,比如'someobj.get'。他們只是在那裏被用作語法糖元編程構造。不是實際的實例方法。這就是'私人'所做的;它阻止你用一個明確的接收者調用一個方法。所以這些方法在使用這種方式時基本上就像Ruby的「關鍵字」一樣。 – Casper 2013-02-13 11:20:48

+0

很好的解釋,謝謝。 – Jonah 2013-02-13 19:13:17