我对来自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
而不是块的原因。
答案 0 :(得分:1)
以表格
define_method(:foo){|x| ...}
:foo
是方法名称,x
是参数。他们有不同的角色。它与:
def foo(x)
...
end