主要问题:在module_function
方法的Ruby API文档中,我看到以下代码示例:
module Mod
def one
"This is one"
end
module_function :one
end
class Cls
include Mod
def call_one
one
end
end
Mod.one #=> "This is one"
c = Cls.new
c.call_one #=> "This is one"
module Mod
def one
"This is the new one"
end
end
Mod.one #=> "This is one"
c.call_one #=> "This is the new one"
如果要正确阅读此代码,我会看到以下内容:
- 定义了一个名为
Mod
的模块以及名为one
的方法。然后调用module_function
方法,将此方法的名称作为参数。 - 定义了一个名为
Cls
的类,并且Mod
模块包含在此类中,从而使该类访问Mod
内定义的方法。然后创建了包装器方法,该方法只将其调用委派给模块方法。 - 模块方法是直接调用的,并且在类的新实例上调用包装方法。两个电话都会返回同一件事。
之后,我感到困惑。然后重新打开该模块,并创建one
方法的新实现。然后,再次执行两个原始方法调用(模块调用和类实例调用),这次使用不同的输出。
如果从相应的方法调用中显示了两个不同的输出,这意味着现在必须在模块中使用两个不同的方法。我对此做出了纠正吗?
相关问题:出于好奇,我尝试了以下代码,但没有产生相同的结果:
module Sprocket
def create
"Sprocket"
end
module_function
def create
"Sprocket 2.0"
end
end
class SprocketFactory
include Sprocket
def make
create
end
end
p Sprocket.create #=> "Sprocket 2.0"
p SprocketFactory.new.make #=> "Sprocket 2.0"
因此,如果两个one
方法同时定义了API示例代码(而不是像文档中所做的那样重新打开模块),那么会是什么样?还是不可能的事情?
如果同时定义了两个
one
方法,则API示例代码会是什么样
module Sprocket
def create
"Sprocket"
end
module_function :create
def create
"Sprocket 2.0"
end
end
您应该想象一个无法恢复的时间表。
第一个示例(使用one
s):引入实例方法one
,将其声明为模块方法,介绍新实例方法one
。模块方法保持不变。
使用create
的代码:介绍一个实例方法create
,为下面使用module_function
声明的所有内容介绍了新的"双"范围,两者都介绍了新模块方法,并重新计算了实例方法。
上面的代码:介绍一个实例方法,将其声明为模块方法,介绍新实例方法。