在下面的代码中,我想调用包含done
内部模块的类的类方法self.hello
说明:
A::bonjour
会致电Mod::hello
,B::ciao
我希望能够在Mod::hello
中检测到“通话类”(A或B),以便能够拨打A::done
或B::done
module Mod
def self.hello
puts "saying hello..."
end
end
class A
include Mod
def self.bonjour
Mod::hello
end
def self.done
puts "fini"
end
end
class B
include Mod
def self.ciao
Mod::hello
end
def self.done
puts "finitto"
end
end
答案 0 :(得分:4)
虽然(也许)不像Niklas的回答那么干净,但它仍然很容易实现,而且IMO比OP中显示的使用模式更清晰,它依赖于知道混合了哪个模块。
(当存在其他方法时,我宁愿不必将参数传递给像这样的mixin方法。)
输出:
pry(main)> A::bonjour
saying hello...
fini
pry(main)> B::ciao
saying hello...
finitto
胆量:
module Mod
module ClassMethods
def hello
puts "saying hello..."
done
end
end
def self.included(clazz)
clazz.extend ClassMethods
end
end
修改后的类声明,删除显式模块引用:
class A
include Mod
def self.bonjour
hello
end
def self.done
puts "fini"
end
end
class B
include Mod
def self.ciao
hello
end
def self.done
puts "finitto"
end
end
您还可以提供done
的默认实施:
module Mod
module ModMethods
def hello
puts "saying hello..."
done
end
def done
throw "Missing implementation of 'done'"
end
end
def self.included(clazz)
clazz.extend ModMethods
end
end
正如对这篇文章的评论指出的那样,如果OP中的片段是对实际用例的忠实表示,那么您也可以使用extend
(而不是include
),让一切都更清洁:
module Mod
def hello
puts "saying hello..."
done
end
def done
raise NotImplementError("Missing implementation of 'done'")
end
end
使用extend
的课程:
class A
extend Mod
def self.bonjour
hello
end
def self.done
puts "fini"
end
end