【问题标题】:Please explain this metaprogramming magic of ruby请解释一下 ruby​​ 的元编程魔法
【发布时间】:2014-02-27 13:59:47
【问题描述】:
module HashInitialized
  def hash_initialized(*fields)
    define_method(:initialize) do |h|
      missing = fields - h.keys
      raise Exception, "Not all fields set: #{missing}" if missing.any?

  h.each do |k,v|
    instance_variable_set("@#{k}", v) if fields.include?(k) 
    end
   end
 end
end

class Cheese
  extend HashInitialized
  attr_accessor :color, :odor, :taste
  hash_initialized :color, :odor, :taste
end

好吧,我明白了:

  1. 我们使用 HashInitialized 中的方法扩展 Cheese 类,因此模块 HashInitialized 中的方法 hash_initialized 可以作为 Cheese 中的类方法使用
  2. 我们将 3 个符号传递给 hash_initialized 方法
  3. 在 hash_initialized 方法中,这 3 个符号由于 * 运算符而被放入称为字段的数组中
  4. 在 hash_initialized 方法中我们定义了初始化方法
  5. 现在是我不明白的部分,|h| 是什么?指的是?为什么我们可以在 |h| 上调用 h.keys。好像是哈希,但我不明白它是如何传递到那里的。
  6. 然后我们迭代这个 |h|哈希,设置实例变量,这里一切都清楚了,除了 |h|响应每个,所以它必须是数组或哈希,我仍然不明白这些值来自哪里。

任何帮助表示赞赏!

代码取自 ruby​​monk.com,元编程 Ruby:Ascent

【问题讨论】:

    标签: ruby metaprogramming


    【解决方案1】:

    define_method(:initialize) do |h|... 使用一个参数 (h) 创建了一个初始化方法。这意味着它创建了一个期望哈希的构造函数。想象一下,创建的代码如下所示:

    class Cheese
    
      def initialize(h)
        missing = fields - h.keys
        raise Exception, "Not all fields set: #{missing}" if missing.any?
    
        h.each do |k,v|
          instance_variable_set("@#{k}", v) if fields.include?(k) 
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2019-08-27
      • 2011-06-28
      • 2017-05-15
      • 2013-03-31
      • 1970-01-01
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      相关资源
      最近更新 更多