【问题标题】:ruby - extend module inside another moduleruby - 在另一个模块中扩展模块
【发布时间】:2018-03-30 06:04:40
【问题描述】:

我正在尝试定义几个模块,以便轻松地将某些实例和类方法添加到其他类中,这就是我正在做的事情:

module Foo
  module Bar
    def speak
      puts "hey there"
    end
  end
  module Baz
    extend Foo::Bar

    def welcome
      puts "welcome, this is an instance method"
    end
  end
end

class Talker
  include Foo::Baz
end

Talker.new.welcome
Talker.speak

这个输出是:

welcome, this is an instance method
undefined method 'speak' for Talker.class (NoMethodError)

我期待 Talker 有 'speak' 方法,因为它包含 Foo::Baz 本身扩展 Foo::Bar。

我错过了什么?

【问题讨论】:

  • 因此,如果我将 Baz 设为一个类而不是一个模块,并且我更改了 Talker 使其成为 Baz 的子类,那么我的示例就可以工作。但是有没有可能在不让 Baz 成为一个类的情况下做我想做的事情? (而且不必像 Talker::Foo::Bar.speak 那样做?)

标签: ruby


【解决方案1】:

你可以试试这个:

module Baz
  extend Foo::Bar

  def self.included(base)
    base.send :extend, Foo::Bar
  end

  def welcome
    puts "welcome, this is an instance method"
  end
end

这将自动扩展包含 Baz 的所有类。

PS:

module Baz中的extend Foo::Bar在原来的sn-p中,这个代码不影响方法def self.included(base)

【讨论】:

  • 为什么 2 扩展 Foo::Bar?一个在里面,一个在外面。
  • 第一个扩展将类级方法从 Foo::Bar 添加到 Baz。第二个将 Foo::Bar 中的方法添加到所有包含 Baz 的类和模块中。
  • 我仍然不明白 extend Foo::Bar 在这个或任何其他情况下有什么用处
  • extend Foo::Bar 在原始代码 sn-p 中,所以我决定把它留在这里。对于这种情况,真的没有必要。我会更新我的答案
【解决方案2】:

试试这个:

class Talker
   extend Foo::Baz
end

由于您想将 Talker.speak 作为类方法而不是作为实例方法(如 Talker.new.speak)调用,因此您必须包含 Foo:Baz,以便类本身采用方法。

一种可能是使用“扩展”(如上),另一种是修改它的特征类:

class Talker
  class << self
    include Foo::Baz
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-24
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    相关资源
    最近更新 更多