ruby - 我可以 "retroactively"从模块添加类方法(在已经包含该模块之后)吗?

标签 ruby module metaprogramming class-method

在 Ruby 中,我可以这样做:

module Foo
end

class Bar
  include Foo
end

module Foo
  def do_something_instancey
    puts "I'm an instance!"
  end
end

然后,如果我实例化一个 Bar 对象,我可以对其调用 do_something_instancey :

b = Bar.new
b.do_something_instancey

但是,如果我这样做...

module Foo
  def self.included(base)
    def base.do_something_classy do
      puts "I'm a class!"
    end
  end
end

我的理解是,因为我在定义该类方法之前将 Foo 包含在 Bar 中,所以我无法调用 Bar.do_something_classy 因为它从未“附加”到 Bar

我意识到这可能有点不准确/不是真正正确的术语。无论如何,在上面的示例中,有没有办法在包含模块后将类方法从 Foo 附加到 Bar

最佳答案

下面是类方法和实例方法的示例:

module Foo
  def self.included(base)
    base.extend(ClassMethods)
  end

   module ClassMethods
   end
end

class Bar
  include Foo
end

module Foo
  def do_something_instancey
    puts "I'm an instance!"
  end

  module ClassMethods
    def do_something_classy
      puts "I'm a class!"
    end
  end
end

b = Bar.new
b.do_something_instancey
# => I'm an instance!
Bar.do_something_classy
# => I'm a class!

要将类方法添加到(已经)包含特定模块的每个类,您可以遍历 Ruby 的 ObjectSpace :

ObjectSpace.each_object(Class) do |klass|
  if klass.include? Foo
    klass.define_singleton_method(:do_something_classy) do
      puts "I'm a class!"
    end
  end
end

关于ruby - 我可以 "retroactively"从模块添加类方法(在已经包含该模块之后)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11633145/

相关文章:

java - java中有getattr、callable等元编程函数吗?

ruby-on-rails - 如何使用 ruby​​-jira Gem 创建远程 JIRA 问题

javascript - 模块解析失败错误 Unexpected token } - Webpack

javascript - Webpack:重复模块加载效率低下吗?

module - 在 OCaml 中从 Map 扩展模块

ruby-on-rails - 如何在Rails应用程序中遍历所有模型?

lisp - 如果 Lisp 源代码基本上是一个 AST,那是否意味着 Lisp 宏是语言不可知的?

ruby-on-rails - 如何找出拦截 'method_missing' 的内容

此实现的 Ruby 正确数据结构

ruby-on-rails - 在嵌套对象中搜索太阳黑子