我定义了以下模块,以及嵌套在模块方法中的模块方法和方法:
module RansackHelpers
def self.split(attribute, model_class)
def run(memo, model_class, attribute)
# Code
end
run([], model_class, attribute)
end
end
如何在run
内拨打self.split
?显然,它没有找到嵌套方法。
答案 0 :(得分:2)
根据 Metaprogramming Ruby 2
,Ruby中有一个当前类概念无论您在Ruby程序中,您始终都有一个当前对象:
self
。同样,您总是拥有当前类(或模块)。由于Ruby解释器始终保持对当前类(或模块)的引用,因此在定义方法时,该方法将成为当前类的实例方法。
它随class
和module
关键字而变化。
当您使用
class
关键字(或带有module
关键字的模块)打开课程时,该课程将成为当前课程。
因此,在您的情况下,当前定义的run
方法的类仍然是RansackHelpers
,而不是RansackHelpers
的单例类。
这里有效,
module RansackHelpers
class << self
def split(attribute, model_class)
def run(memo, model_class, attribute)
# Code
end
run([], model_class, attribute)
end
end
end
答案 1 :(得分:1)
There is no such thing as a nested method in Ruby。如果您在run
之前致电split
,您将收到NoMethod错误。如果你两次调用split,你会得到一个警告:&#34;警告:方法重新定义;放弃旧跑。&#34;
您有一个方法split
,它在调用时定义了另一种方法。
答案 2 :(得分:1)
如果您想拥有“本地功能”,可以使用lambdas进行模拟。
module RansackHelpers
def self.split(attribute, model_class)
run = ->(memo, model_class, attribute) do
# Code
end
run.call([], model_class, attribute)
end
end
从这个例子来看,为什么你想要这样做并不明显。如果它被立即定义和调用,您也可以直接执行函数体。如果要从外部使用它,你应该创建一个普通的,而不是嵌套的方法。
对于递归调用,这应该就是事情。