Ruby-动态定义模块

5

以下是我在项目中使用的示例模块(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

错误截图:您可以看到在最后一行中说它没有完成。

输入图像描述


“Is not working” 不是一个好的定义。问题出在哪里?你收到了什么错误信息? - Ed de Almeida
没有错误。当我在 irb 中尝试时,命令提示仍然显示该方法未以 end 结束。为什么“`”不是一个好的定义? - Mr. Black
1
为什么这不是一个好的定义?因为你没有提供任何关于错误消息的详细信息,例如堆栈跟踪等。请提供尽可能多的(相关)细节,以便我们能够轻松地理解问题。也许您可以阐明为什么要实现这样的东西? - Pascal
@pascalbetz解释得很好,为什么这不是一个好的定义。 - Ed de Almeida
正如我所说,我没有遇到任何错误。我已经更新了在“irb”中尝试的快照。 - Mr. Black
2个回答

14
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" 

4
NB:我会使用Cary提供的解决方案,因为它更符合惯用语。 现在让我们回答OP所述的问题。
问题出在heredoc上。
Object.class_eval <<TES

需要以TES 在第一个位置结束。按照您的方式关闭,请使用:

#                   ⇓ HERE
Object.class_eval <<-TES

谢谢。它正在工作。你能告诉我“-”的用途是什么吗? - Mr. Black
@Mr.Black:它允许对闭合标识符进行一些缩进。http://ruby-doc.org/core-2.2.0/doc/syntax/literals_rdoc.html - Sergio Tulentsev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接