以下是来自Why's Poignant Guide to Ruby Chapter 6的Ruby代码片段,作者试图展示Ruby中的元编程:
如果我理解正确的话,这段代码会将给定名称和值添加到@traits中。 是这样吗? 感谢您的帮助,以下是完整的源代码,可能对想要查看它的任何人都有帮助:
# Get a metaclass for this class
def self.metaclass; class << self; self; end; end
我不太熟悉Ruby,但是这个展开后的形式是这样的吗?
def self.metaclass
def self.self
end
end
我理解的是这样。然而,我仍然不理解这段代码确切地做了什么。它的目的是什么?
在代码中进一步说明,为什么添加这个:
arr.each do |a|
metaclass.instance_eval do
define_method( a ) do |val|
@traits ||= {}
@traits[a] = val
end
end
end
如果我理解正确的话,这段代码会将给定名称和值添加到@traits中。 是这样吗? 感谢您的帮助,以下是完整的源代码,可能对想要查看它的任何人都有帮助:
# 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