将参数传递给define_method和下一个块之间的区别?

时间:2013-08-10 18:16:33

标签: ruby metaprogramming

我对来自Poignant Guide的以下代码感到困惑:

# The guts of life force within Dwemthy's Array
class Creature

  # Get a metaclass for this class
  def self.metaclass; class << self; self; end; end

  # Advanced metaprogramming code for nice, clean traits
  def self.traits( *arr )
    return @traits if arr.empty?

    # 1. Set up accessors for each variable
    attr_accessor( *arr )

    # 2. Add a new class method to for each trait.
    arr.each do |a|
      metaclass.instance_eval do
        define_method( a ) do |val|
          @traits ||= {}
          @traits[a] = val
        end
      end
    end

    # 3. For each monster, the `initialize' method
    #    should use the default number for each trait.
    class_eval do
      define_method( :initialize ) do
        self.class.traits.each do |k,v|
          instance_variable_set("@#{k}", v)
        end
      end
    end

  end

  # Creature attributes are read-only
  traits :life, :strength, :charisma, :weapon
end

以上代码用于创建新类,如下所示:

class Dragon < Creature
  life( 1340 )     # tough scales
  strength( 451 )  # bristling veins
  charisma( 1020 ) # toothy smile
  weapon( 939 )    # fire breath
end

我需要更多地研究元编程的基础知识,但是现在我只想知道val阻塞参数在define_method( a ) do |val|中的来源?它表示分配给每个特征的点值,但我不明白这些数字中的每一个如何成为块参数。

另外,为什么a在括号中传递给define_method,而val作为块参数传递?

我已经阅读了关于define_method参数主题的this question,但它没有说明将参数传递给define_method而不是块的原因。

1 个答案:

答案 0 :(得分:1)

以表格

define_method(:foo){|x| ...}

:foo是方法名称,x是参数。他们有不同的角色。它与:

相同
def foo(x)
  ...
end