In the code below, I would like to call the class method done
of the class that includes the module from inside self.hello
在下面的代码中,我想调用包含self.hello中的模块的类的类方法
Explanation:
A::bonjour
will call Mod::hello
so will B::ciao
A :: bonjour将调用Mod :: hello,因此B :: ciao将会调用
I would like to be able to detect the "calling class" (A or B) in Mod::hello
in order to be able to call the A::done
or B::done
我希望能够在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
1 个解决方案
#1
3
While (perhaps) not as clean as Niklas' answer, it's still easily doable, and IMO cleaner than the usage pattern shown in the OP which relies on knowing which module is mixed in.
虽然(也许)不像Niklas的回答那么干净,但它仍然很容易实现,而且IMO比OP中显示的使用模式更清洁,它依赖于知道混合了哪个模块。
(I prefer not having to pass an argument to mixin methods like this when other means exist.)
(当存在其他方法时,我更喜欢不必将参数传递给mixin方法。)
The output:
pry(main)> A::bonjour
saying hello...
fini
pry(main)> B::ciao
saying hello...
finitto
The guts:
module Mod
module ClassMethods
def hello
puts "saying hello..."
done
end
end
def self.included(clazz)
clazz.extend ClassMethods
end
end
The modified class declarations, removing the explicit module reference:
修改后的类声明,删除显式模块引用:
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
You may also supply a default implementation of 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
As a comment to this post points out, if the snippet in the OP is a faithful representation of the actual usecase, you might as well use extend
(instead of include
), leaving everything cleaner:
正如对这篇文章的评论所指出的,如果OP中的片段是对实际用例的忠实表示,那么你也可以使用extend(而不是include),让一切都更清晰:
module Mod
def hello
puts "saying hello..."
done
end
def done
raise NotImplementError("Missing implementation of 'done'")
end
end
And the classes using extend
:
使用扩展的类:
class A
extend Mod
def self.bonjour
hello
end
def self.done
puts "fini"
end
end
#1
3
While (perhaps) not as clean as Niklas' answer, it's still easily doable, and IMO cleaner than the usage pattern shown in the OP which relies on knowing which module is mixed in.
虽然(也许)不像Niklas的回答那么干净,但它仍然很容易实现,而且IMO比OP中显示的使用模式更清洁,它依赖于知道混合了哪个模块。
(I prefer not having to pass an argument to mixin methods like this when other means exist.)
(当存在其他方法时,我更喜欢不必将参数传递给mixin方法。)
The output:
pry(main)> A::bonjour
saying hello...
fini
pry(main)> B::ciao
saying hello...
finitto
The guts:
module Mod
module ClassMethods
def hello
puts "saying hello..."
done
end
end
def self.included(clazz)
clazz.extend ClassMethods
end
end
The modified class declarations, removing the explicit module reference:
修改后的类声明,删除显式模块引用:
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
You may also supply a default implementation of 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
As a comment to this post points out, if the snippet in the OP is a faithful representation of the actual usecase, you might as well use extend
(instead of include
), leaving everything cleaner:
正如对这篇文章的评论所指出的,如果OP中的片段是对实际用例的忠实表示,那么你也可以使用extend(而不是include),让一切都更清晰:
module Mod
def hello
puts "saying hello..."
done
end
def done
raise NotImplementError("Missing implementation of 'done'")
end
end
And the classes using extend
:
使用扩展的类:
class A
extend Mod
def self.bonjour
hello
end
def self.done
puts "fini"
end
end