【问题标题】:Get included module name in module's method [closed]在模块的方法中获取包含的模块名称[关闭]
【发布时间】:2012-12-14 06:12:28
【问题描述】:

是否可以获取包含在其类方法中的模块名称?

满足以下示例的部分代码:

module Helper
  def module_name
    # return module name for which method is being called
  end

  def new_module
    name = module_name
    define_method :initialize_module do
      extend foo? ? Object.const_get("New#{name}") : Object.const_get("Old#{name}")
    end
  end
end

module A
  extend Helper
  new_module

  module NewA
    def some_method
      'Successfully extended NewA'
    end
  end

  module OldA
    def some_method
      'Successfully extended OldA'
    end
  end
end

class B
  include A

  def initialize
    initialize_module
  end 

  def foo?
    true
  end
end

class C
  include A

  def initialize
    initialize_module
  end 

  def foo?
    false
  end
end

B.new.some_method
#=> 'Successfully extended NewA'

C.new.some_method
#=> 'Successfully extended OldA'

【问题讨论】:

  • 当你包含多个模块时怎么办?
  • 你说得对,我已经更新了更具体的示例。

标签: ruby metaprogramming


【解决方案1】:

我以前从未需要动态定义 module 扩展方法,在 class 上管理异常困难,但您始终可以使用中间模块来帮助打包和导入方法来管理它:

module Helper
  def self.extended(base)
    base_name = base.to_s

    extension = Module.new

    extension.send(:define_method, :module_name) do
      base_name
    end

    base.send(:extend, extension)
  end
end

module A
  extend Helper
end

module B
  extend Helper
end

A.module_name
# => "A"

B.module_name
# => "B"

这可能比定义模块实例变量要简单得多。在实践中,闭包往往更干净。

【讨论】:

  • 谢谢!这就是我要找的!
【解决方案2】:
module A
  def module_name
    A.class_name
  end
end

class B
  include A
end

B.new.module_name  # => 'A'

【讨论】:

  • 我提供的例子不够具体——我已经更新了。请看一下。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2012-07-27
  • 2016-03-01
  • 2013-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多