2013-12-20 155 views
2

因此,在一個Ruby類,你可以用一個成語,如class << self類似如下:紅寶石:打開模塊的單

class SalesOrganization 
    def self.find_new_leads 
    ... 
    end 
    class << self 
    include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation 
    add_transaction_tracer :find_new_leads, :category => :task 
    end 
end 

我的問題是,如果SalesOrganization是實際上是一個Module,而不是Class什麼。這是做我希望它會做什麼,或者我打開了一些我不該涉及的黑魔法?

# Potentially terrible code 
module SalesOrganization 
     def self.find_new_leads 
     ... 
     end 
     class << self 
     include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation 
     add_transaction_tracer :find_new_leads, :category => :task 
     end 
end 

如何訪問模塊單例類?

回答

3

不,你沒有釋放任何黑魔法。您可以在任何物體上定義特殊方法,包括模塊(該Module類的一個實例):

module M 
    def self.b 
    "b" 
    end 
end 

M.b # => "b" 

module M 
    class << self 
    def c 
     "c" 
    end 
    end 
end 

M.c # => "c" 

您還可以,如果你的方法使用instance_eval

module M; end 

def M.a 
    "a" 
end 

M.a # => "a" 

你認爲工作太接近定義不知道,直到運行時:

module M; end 

M.instance_eval <<EOF 
    def d 
    "d" 
    end 
EOF 

M.d # => "d" 

當然,像NewRelic...模塊可以使關於C假設它們包含在其中的模塊/模塊,因此您必須在那裏小心。

1

我不確定我是否理解你想存檔的內容。但是,如果要將包含C的定義寫入模塊B。而不是使用CA包括B後,比你能做到這一點是這樣的:

module B 
    def self.included(base) 
    base.include C 
    end 
end 

class A 
    include B 

    # use C 
end 

這是你的榜樣:

module SalesOrganization 
    def self.included(base) 
    base.include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation 
    base.add_transaction_tracer :find_new_leads, :category => :task 
    end 


    def self.find_new_leads 
    ... 
    end 
end 

如果你現在包括SalesOrganization模塊插入類的類將包括新的東西。

+0

這實際上並不回答關於如何打開模塊的單例類的原始問題。我不包括該模塊的任何地方,包括的方法將永遠不會觸發。我現在只是將它用作命名空間。 – randombits