2017-09-05 82 views
-1

假設我有一個模塊:如何從Ruby中的實例方法訪問模塊?

module M 
    def self.foo 
    ... 
    end 

    def bar 
    ... 
    end 
end 

M模塊被包括在一類。

class A 
    include M 
end 

我想打電話給foobar,最終將上A實例調用。在bar內部完成此操作的最佳方法是什麼?

當然,我可以說M.foo,但這是模塊名稱的重複,這是不必要的。

+0

_「我想從酒吧叫foo」_ - 如果除了'M.foo'之外還有'A.foo',哪個'foo'想要打電話? – Stefan

+3

爲什麼你不想使用'M.foo'?在我看來,這是合乎邏輯的事情。將類方法和實例方法放在同一個模塊中看起來很奇怪,考慮到你想調用第一個幷包含第二個。 –

+1

「A」和「M」的單例類之間沒有任何關係。特別是,'M'的單例類不在'A'的繼承鏈中。 –

回答

1

通常,在module,這是一個很好的做法,類方法和實例的方法分離出來,像這樣:現在

module M 
    def bar 
    puts "BAR" 
    self.class.foo 
    end 

    module ClassMethods 
    def foo 
     puts "FOO" 
    end 
    end 
end 

,在一個班,我會非常想include這個模塊M以一種方式,我得到A.foo作爲類的方法和A.new.bar作爲實例方法。這個技巧是Module.included

module M 
    def bar 
    puts "BAR" 
    self.class.foo 
    end 

    module ClassMethods 
    def foo 
     puts "FOO" 
    end 
    end 

    # when module is included, extend the class with ClassMethods 
    def self.included(base) 
    base.extend ClassMethods 
    end 
end 

class A 
    include M 
end 

A.singleton_methods #=> [:foo] 

A.new.foo 
#=> BAR 
#=> FOO 

通過這種方法,您可以參閱類方法與self.class,它會自動地工作。

希望它有幫助。

+0

謝謝,我沒有想到這個!由於似乎沒有避免在'A'中包含'foo'的解決方案,我明白爲什麼要感謝Jorg的評論,我會接受這個答案,因爲它最接近我想要的。 –

0

不是真的優雅,但

def bar 
    Module.nesting.last.foo 
end 

應該這樣做。

請注意Module#nesting返回一個數組,因爲一個模塊可能嵌套到另一個模塊中。在一般情況下,你需要應用正確的數組索引來選擇你想要的模塊。

0

我認爲使用M.foo是最好的,但作爲一個練習,可以按如下方式更改M#bar

module M 
    def self.foo 
    puts "In self.foo" 
    end 

    def bar 
    puts "In bar" 
    method(__method__).owner.foo 
    end 
end 

class A 
    include M 
end 

a = A.new 
a.bar 
    # In bar 
    # In self.foo 
+0

考慮使用'__caller__'而不是'__method__'來使別名方法成爲可能,並使代碼仍然有效。 – mudasobwa