我想在Ruby模块中放置一个方法,以便可以使用简单的语法从类方法或调用实例方法:
module MyMod
def fmt *args
args.map { | a | "You said #{a}" }
end
end
class MyClass
include MyMod
def inst
puts fmt 1,2,3
end
def self.cls
puts fmt 4,5,6
end
end
上述方法不起作用,因为类方法(cls
)无法看到实例方法fmt。如果我将定义更改为self.fmt
,则实例方法必须将其作为MyMod.fmt
调用。
我希望能够从这两种方法中调用fmt (some stuff)
。这样做有“ruby-ish”方式吗?我可以将模块定义为
module MyMod
def self.fmt *args
args.map { | a | "You said #{a}" }
end
def fmt *args
MyMod.fmt args
end
end
但那不是很干,是吗?有更简单的方法吗?
答案 0 :(得分:5)
你可以利用Module#included
方法做到这一点:
module MyMod
# here base is a class the module is included into
def self.included(base)
# extend includes all methods of the module as class methods
# into the target class
base.extend self
end
def fmt(*args)
args.map { |a| "You said #{a}" }
end
end
class MyClass
# regular include provides us with instance methods
# and defined above MyMod#included hook - with class methods
include MyMod
def inst
puts fmt(1, 2, 3)
end
def self.cls
puts fmt(4, 5, 6)
end
end
puts MyClass.cls
puts MyClass.new.inst
这是输出:
You said 4
You said 5
You said 6
You said 1
You said 2
You said 3
有关更详细的说明,请查看this article。
答案 1 :(得分:1)
include
extend
模块中的MyMod
和MyClass
,以便将fmt
方法作为实例和类方法添加到{ {1}}。
MyClass
的作用是将模块的方法添加到单个实例中。在这种情况下,该实例就是类本身,这就是为什么这些方法可以作为类方法使用的原因。