为什么模块的'自我'方法不能成为类的单一方法?

问题描述:

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://*.com/questions/4699355/is-that-possible-to-define -a-class-method-in-a-module) – 2012-04-06 04:19:24

如果你想拥有包括模块时,混合成一个类两种类方法和实例方法,你可以遵循的模式:

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

包含模块类似于复制其实例方法。

在您的示例中,没有实例方法可以复制到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