2012-04-06 73 views
15
module Test 
    def self.model_method 
    puts "this is a module method" 
    end 
end 

class A 
    include Test 
end 

A.model_method 

這與將錯誤:爲什麼模塊的'自我'方法不能成爲類的單一方法?

未定義的方法`model_method」爲答:類(NoMethodError)

但是當我使用A的元類它的工作原理:

module Test 
    def model_method 
    puts "this is a module method" 
    end 
end 

class A 
    class << self 
    include Test 
    end 
end 

A.model_method 

有人可以解釋這一點嗎?

+1

可能重複的[?這是可能的模塊中定義的一類方法](http://stackoverflow.com/questions/4699355/is-that-possible-to-define -a-class-method-in-a-module) – 2012-04-06 04:19:24

回答

32

如果你想擁有包括模塊時,混合成一個類兩種類方法和實例方法,你可以遵循的模式:

module YourModule 
    module ClassMethods 
    def a_class_method 
     puts "I'm a class method" 
    end 
    end 

    def an_instance_method 
    puts "I'm an instance method" 
    end 

    def self.included(base) 
    base.extend ClassMethods 
    end 
end 

class Whatever 
    include YourModule 
end 

Whatever.a_class_method 
# => I'm a class method 

Whatever.new.an_instance_method 
# => I'm an instance method 

基本上過度簡化它,你extend添加類的方法並且您include添加實例方法。當包含一個模塊時,將調用#included方法,並將其包含在實際的類中。從這裏您可以從另一個模塊的某個類方法中獲得該類。這是一個相當普遍的模式。

參見:http://api.rubyonrails.org/classes/ActiveSupport/Concern.html

11

包含模塊類似於複製其實例方法。

在您的示例中,沒有實例方法可以複製到Amodel_method實際上是一個Test的單例類的實例方法。


考慮:

module A 
    def method 
    end 
end 

此:

module B 
    include A 
end 

類似於此:

module B 
    def method 
    end 
end 

當你想到它是這樣的,這是非常合情合理的:

module B 
    class << self 
    include A 
    end 
end 

B.method 

這裏,方法被複制到B模塊的單例類,這使得它們成爲B的「類方法」。

注意,這是完全一樣的事情:

module B 
    extend A 
end 

在現實中,這些方法不被複制; 沒有重複。該模塊只包含在方法查找列表中。

+1

對於像我這樣的初學者來說,這個討論的區別在於延伸和包含在http://www.railstips。org/blog/archives/2009/05/15/include-vs-extend-in-ruby /在閱讀這篇文章時很有幫助。 – 2016-02-16 16:17:02

相關問題