【问题标题】:Call method of included module from class从类中调用包含模块的方法
【发布时间】:2016-04-28 06:55:04
【问题描述】:

我有一个用例,我有class A,其中包括module B

class A
  include B

  def do_one_thing
    # override module's method. do something different instead
  end

  def do_another_thing
    # Call `do_one_thing` from here,
    # but call the module's method, not the one I overrode above.
  end
end

module B
  included do
    def do_one_thing
      # ...
    end
  end

  # some other methods
end

如上所示,我从do_another_thing 拨打do_one_thing。我的问题是我需要调用模块的方法(即super 方法)。这在 Rails 中可行吗?

【问题讨论】:

标签: ruby-on-rails ruby inheritance module super


【解决方案1】:

要使用included 方法,您需要将B 模块转换为extend ActiveSupport::Concern,但这不会给您想要的行为。

如果我是你,我会放弃这种模式并使用简单的原生 Ruby 模块模式:

module B    
  def do_one_thing
    puts 'in module'
    # ...
  end

  # some other methods
end

class A
  include B

  def do_one_thing  
    super  
    puts 'in class'
    # override module's method. do something different instead
  end

  def do_another_thing
    do_one_thing
    # Call `do_one_thing` from here,
    # but call the module's method, not the one I overrode above.
  end
end

A.new.do_one_thing

以上代码将正确使用您正在寻找的模块继承。

Read more about Ruby module inheritance here

【讨论】:

  • 谢谢!很抱歉我迟到的答案。这样做的问题是我只需要调用模块的方法(而不运行类的方法)。在其他情况下,我只需要调用类方法,而不运行模块的方法...
  • 您有几个选择。听起来你真正想要的是两种可以在不同地方调用的方法。如果这还不够,您可以尝试使用 Refinements。改进类似于猴子补丁,但影响范围更有限。我写了一篇关于 using Ruby Refinements 的帖子,这可能是一个有用的介绍。
【解决方案2】:

您可以在覆盖之前“保存”包含的方法

module B
  extend ActiveSupport::Concern

  included do
    def do_one_thing
      puts 'do_one_thing'
    end
  end
end

class A
  include B

  alias_method :old_do_one_thing, :do_one_thing
  def do_one_thing
    puts "I'd rather do this"
  end

  def do_another_thing
    old_do_one_thing
  end
end

a= A.new
a.do_one_thing
a.do_another_thing

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    相关资源
    最近更新 更多