在模块的方法中获取包含的模块名称

时间:2012-12-14 06:12:28

标签: ruby metaprogramming

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

满足以下示例的一些代码:

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'

2 个答案:

答案 0 :(得分:4)

我之前从未动态定义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"

这可能比定义模块实例变量要麻烦得多。在实践中,关闭往往更清洁。

答案 1 :(得分:1)

module A
  def module_name
    A.class_name
  end
end

class B
  include A
end

B.new.module_name  # => 'A'