ruby-动态定义模块

时间:2016-05-11 06:36:09

标签: ruby dynamic metaprogramming

在我的项目中使用的示例模块(n个数字)下面,它们具有相同的方法名称,具有不同的返回值(带模块名称的前缀)。

module Example1
 def self.ex_method
   'example1_with_'
 end
end


module Example2
 def self.ex_method
   'example2_with_'
 end
end

我尝试使用类似#define_method的元编程方式来完成此操作。但是,这对我不起作用。有没有办法做到这一点?

array.each do |name|
  Object.class_eval <<TES
    module #{name}
      def self.ex_method
        "#{name.downcase}_with_"
      end
    end
  TES
end

错误捕捉:您可以在最后一行看到它没有完成。

enter image description here

2 个答案:

答案 0 :(得分:8)

m = Object.const_set("Example1", Module.new)
  #=> Example1 
m.define_singleton_method("ex_method") { 'example1_with' }
  #=> :ex_method  

让我们看看:

Example1.is_a? Module
  #=> true
Example1.methods.include?(:ex_method)
  #=> true
Example1.ex_method
  #=> "example1_with" 

答案 1 :(得分:4)

NB :我会使用Cary提供的解决方案,因为它更具惯用性。

现在让我们回答OP中所述的问题。

问题在于heredoc

Object.class_eval <<TES

将在第一个位置关闭TES 。要像你一样关闭,请使用:

#                   ⇓ HERE
Object.class_eval <<-TES