Ruby 模板模块

标签 ruby templates metaprogramming

假设我有一系列相关模块:

module Has_Chocolate
   def has_chocolate?
      true
   end
end

module Has_Cake
   def has_cake?
      true
   end
end

. . .

我将如何构建模板模块 Has_Something,其中 Something 将作为模块的参数?

最佳答案

模块在其封装上下文中是常量,对于顶层是内核。这让我们可以使用 const_get 获取模块。试试这个:

module Has_Something
  def has(*items)
    items.each do |item|
      mod = Kernel.const_get("Has_" + item.to_s.capitalize)
      instance_eval { include mod }
    end
  end
end

class Baker
  extend Has_Something
  has :cake
end

class CandyMan
  extend Has_Something
  has :chocolate
end

class ChocolateCake
  extend Has_Something
  has :cake, :chocolate
end

如果您更喜欢 include 而不是 extend,您也可以这样做:

module Has_Something
  def self.included(base)
    base.extend HasTemplate
  end

  module HasTemplate
    def has(*items)
      items.each do |item|
        mod = Kernel.const_get("Has_" + item.to_s.capitalize)
        instance_eval { include mod }
      end
    end
  end
end

class Baker
  include Has_Something
  has :cake
end

class CandyMan
  include Has_Something
  has :chocolate
end

class ChocolateCake
  include Has_Something
  has :cake, :chocolate
end

无论哪种情况,此代码都是相同的:

steve = Baker.new
bob = CandyMan.new
delicious = ChocolateCake.new
steve.has_cake? && bob.has_chocolate?  # => true
delicious.has_cake? && delicious.has_chocolate?  #=> true

编辑:

根据您的评论,您正在寻找一种自动创建格式为 has_something? 的方法的方法。这更容易做到:

module Has_Something
  def has (*items)
    items.each do |item|
      method_name = ('has_' + item.to_s + '?').to_sym
      send :define_method, method_name do
        true
      end
    end
  end
end

class Baker
  extend Has_Something
  has :cake
end

class CandyMan
  extend Has_Something
  has :chocolate
end

class ChocolateCake
  extend Has_Something
  has :cake, :chocolate
end

steve = Baker.new
bob = CandyMan.new
delicious = ChocolateCake.new

steve.has_cake? && bob.has_chocolate?  # => true
delicious.has_cake? && delicious.has_chocolate?  # => true

关于Ruby 模板模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1153536/

相关文章:

go - 如何使用golang进行.docx模板(表格内容)

c++ - 创建一个依赖于模板类型的值常量

lisp - 可以订车!和设置CDR!被实现为宏?

javascript - Rails - 格式和渲染 - 它们如何工作?

html - Rails 使用复选框为帖子添加标签(多对多)

php - 轻量级基于 PHP5 的模板类/系统

C++根据其模板定义一个类成员类型

metaprogramming - 如何在SML中自动构造有序数据类型

ruby - 我需要将一个巨大的 csv 文件中的 3 列复制到一个新的 csv 文件中。怎么做?

ruby - 正则表达式:捕获多个相似 block