Cod*_*rer 2 ruby module mixins
我想在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
Run Code Online (Sandbox Code Playgroud)
上面的方法不起作用,因为类method(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
Run Code Online (Sandbox Code Playgroud)
但那不是很干,是吗?有更简单的方法吗?
你可以利用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
Run Code Online (Sandbox Code Playgroud)
这是输出:
You said 4
You said 5
You said 6
You said 1
You said 2
You said 3
Run Code Online (Sandbox Code Playgroud)
有关更详细的说明,请查看本文.