module Test
def self.model_method
puts "this is a module method"
end
end
class A
include Test
end
A.model_method
Run Code Online (Sandbox Code Playgroud)
这将是错误的:
A:Class的未定义方法`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
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下吗?
d11*_*wtq 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
Run Code Online (Sandbox Code Playgroud)
基本上过度简化它,您extend
可以添加类方法并include
添加实例方法.当包含一个模块时,它的#included
方法被调用,它包含在它的实际类中.从这里你可以extend
使用另一个模块中的一些类方法.这是一种非常常见的模式.
另见:http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
Mat*_*ira 11
包含模块类似于复制其实例方法.
在您的示例中,没有要复制到的实例方法A
.model_method
实际上是Test
单例类的实例方法.
鉴于:
module A
def method
end
end
Run Code Online (Sandbox Code Playgroud)
这个:
module B
include A
end
Run Code Online (Sandbox Code Playgroud)
类似于:
module B
def method
end
end
Run Code Online (Sandbox Code Playgroud)
当你以这种方式想到它时,这是完全合理的:
module B
class << self
include A
end
end
B.method
Run Code Online (Sandbox Code Playgroud)
这里,方法被复制到B
模块的单例类中,这使得它们成为"类方法" B
.
请注意,这与以下内容完全相同:
module B
extend A
end
Run Code Online (Sandbox Code Playgroud)
实际上,这些方法并没有被复制; 没有重复.该模块只包含在方法查找列表中.