如果已在类中重写该方法,是否可以调用模块中定义的方法。
Class A
include bmodule
def greeting
super if some_condition_is_true
end
end
module bmodule
included do
has_many :greeters
def greeting
puts 'hi'
end
end
end
A.new.greeting
如果some_condition_is_true为true,则需要打bmodule的问候
我尝试在模块前面加上它,但它没有用。有可能这样做吗?
答案 0 :(得分:1)
您必须先保存原始方法,然后再覆盖它:
Class A
include bmodule
alias_method :original_greeting, :greeting
def greeting
original_greeting if some_condition_is_true
end
end
的示例
答案 1 :(得分:0)
module B
def x
1
end
end
class A
include B
def x
super + 1
end
end
puts A.new.x
# => 2
带有Rails问题的included do
块是,因此您可以在基础上调用类方法。因此,我认为您无需在这种情况下使用它。
答案 2 :(得分:0)
您可以使用方法Method#super_method,该方法提供了很大的灵活性。
module M1
def meth(arg)
yield arg
end
end
module M2
def meth(arg)
yield arg
end
end
class C
include M1
include M2
def meth(arg)
yield arg
end
def test(cond, &block)
case cond
when :C
meth(cond, &block)
when :M2
method(:meth).super_method.call(cond, &block)
when :M1
(method(:meth).super_method).super_method.call(cond, &block)
end
end
end
C.ancestors
#=> [C, M2, M1, Object, Kernel, BasicObject]
c = C.new
c.test(:C) { |m| "meth is from #{m}" }
#=> "meth is from C"
c.test(:M2) { |m| "meth is from #{m}" }
#=> "meth is from M2"
c.test(:M1) { |m| "meth is from #{m}" }
#=> "meth is from M1"
如果由于某种原因您想使用prepend
而不是include
,则C.ancesors
如下:
class C
prepend M1
prepend M2
end
C.ancestors
#=> [M2, M1, C, Object, Kernel, BasicObject]
所以您只需相应地修改test
。
答案 3 :(得分:0)
是的,您可以做到,而且您几乎正确。只需1)大写Bmodule
,以便红宝石不会对您大叫,2)定义A时使用小写的class
,3)包含ActiveSupport ::关注是否使用included
,以及4 )将greeting方法从包含的块中移出。包含的块用于在类级别运行事物,并且实例方法定义不应位于其中。
module Bmodule
extend ActiveSupport::Concern
included do
has_many :greeters
end
def greeting
puts 'hi'
end
end
class A
include Bmodule
def greeting
super if some_condition_is_true
end
end
A.new.greeting