假设我们的代码看起来像这样
module TM
def aa
puts "aa"
end
def bb
TM::aa
end
module_function :bb
end
TM.bb
为什么bb无法通过“TM :: aa”,“self.aa”或“TM.aa”访问aa?它们属于同一模块。设置此类限制有什么好处?如何解决“未定义方法”错误?
答案 0 :(得分:4)
你的意思是这样吗?
module TM
class << self
def aa
puts "aa"
end
def bb
TM::aa
end
end
end
TM.bb
更新您定义它们的方法可以作为实例方法在include
您的模块或类方法时extend
您的类
module TM
def aa
puts "aa"
end
def bb
aa
end
end
class A
include TM
end
class B
extend TM
end
A.new.bb
B.bb
答案 1 :(得分:1)
因为aa
是一个实例函数。如果将其添加到module_function
列表中(或使用声明模块方法的许多其他方法之一),一切正常。就个人而言,我更喜欢:
module TM
def self.aa
puts "aa"
end
def self.bb
TM::aa
end
end
TM.bb
答案 2 :(得分:1)
这不起作用,因为您正在定义实例方法(def aa)而不是模块方法(def self.aa)。
查看文档:
模块是方法和常量的集合。模块中的方法可以是实例方法或模块方法。当包含模块时,实例方法在类中显示为方法,而模块方法则不包括。相反,可以在不创建封装对象的情况下调用模块方法,而实例方法则可以不调用。 (参见Module#module_function)
所以你想要的可能是:
module TM
def self.aa
puts "aa"
end
def bb
TM::aa
end
module_function :bb
end
TM.bb
答案 3 :(得分:1)
我认为你可能会对调用module_function的功能感到困惑,因为这个方法实际上创建了方法的副本并使原始方法变为私有,并将副本混合到元类(或任意类中)案例一步进入方法查找链)。这样就可以在不影响方法的内部使用的情况下覆盖它,即使其在私人使用时安全,同时也可公开使用或公开覆盖。它只是复制到无法访问aa的元类中的副本,因为它在查找链中不存在于其上方。如果两个方法都传递给模块函数,那么您将无法获得未定义的方法错误。