考虑以下代码:
module ModName
def aux
puts 'aux'
end
end
如果我们将module
替换为class
,就可以做到以下操作:ModName.new.aux
模块无法实例化,但是有没有一种方法可以在模块上调用aux
方法呢?
你可以这样做:
module ModName
def aux
puts 'aux'
end
module_function :aux
end
然后只需调用它:
ModName.aux
module_function
传递参数,则下面的任何函数都将成为模块函数。它的工作方式与 private
相同。 - LandonSchropp考虑一下 aux
是什么。哪个对象会响应 aux
?这是一个实例方法,这意味着包括 ModName 的类的实例将对其进行响应。ModName 模块本身不是这样一个类的实例。如果你将 ModName 定义为一个类,那么这也不会起作用 - 你不能在没有实例的情况下调用实例方法。
模块非常像可以混入到其他类中以添加行为的类。当一个类混入一个模块时,所有模块的实例方法都成为该类的实例方法。这是实现多重继承的一种方式。
它们还可以作为命名空间的替代品,因为每个模块定义了一个命名空间。但这与此无关。(顺便说一句,类也有它们自己的命名空间,但将其制作为类意味着您将创建它的实例,所以从概念上讲就是错误的。)
helper
方法中,它接受一个模块并将其混合到请求中。如果您的模块方法不依赖于状态(例如格式化传递给它的字符串的函数),它们也可以被作为MyHelperModule.foo(bar)
外部调用。使用 module_function
(根据@JPabloFernández下面的答案)允许单个模块'实例'方法被访问到OP所请求的方式。 - Phrogzmodule ModName
extend self
def aux
puts 'aux'
end
end
然后你可以正常地导入模块,但也可以通过 ModName 调用方法。
And a little more...
module Y
def Y.a
puts "a"
end
def Y.b
c
end
def self.c
puts "b -- c"
end
end
调用(不带'.new'):
Y.a #=> "a"
Y.b #=> "b -- c"
Y.c #=> "b -- c"
Y.c
也可以。你还可以使用 module Y; class << self; def c; puts "b -- c"; end; end;
并在其特殊类上定义 ::c
。 - Michael De Silvaclass Foo
include ModName
end
Foo.new.aux
# output: aux
Object.new.extend(ModeName).aux
。该语句不需要解释其含义,我的任务是将其翻译为通俗易懂的中文并保持原意。 - AJcodez