我在Ruby(1.9.3)中编写了一小段代码,我使用了一对简单的“类似enum”的类,用 const_set 定义一些常量和一些行为这些常数(例如,天类可能有常量 MON , TUE ...和天数:: MON.succ < / strong>应评估为 TUE )。
我对这些课程非常满意。然而,在增加我的代码时,我有时需要添加更多代码,而且我不喜欢有五个或更多类共享99%源代码的想法,例如:
class Days
NAMES = %w( MON TUE ... )
INSTANCES = []
def initialize(num)
@num = num
end
# An example operation
def +(n)
INSTANCES[(@num + n) % INSTANCES.length]
end
# Another example operation
def succ
self + 1
end
def to_s
NAMES[@num]
end
NAMES.each_with_index do |name, idx|
instance = new(idx)
INSTANCES[idx] = instance
const_set name, instance
end
end
class Months
NAMES = %w( JAN FEB ... )
...
end
我想知道Ruby的元编程功能是否可用于生成这些类。但是,我很难创建 NAMES , INSTANCES 和“enum-named”常量(例如 MON , TUE ,...)。 const_set 是类的类方法,在此代码中它的上下文( self 的值)分别为天和几个月。
创建工厂方法时,我不得不这样做:
def enum_new(names_array)
Class.new do
const_set "NAMES" []
names_array.each_with_index do |name, idx|
NAMES[idx] = name
end
...
end
end
Days = enum_new(%w| MON TUE ... |)
Months = enum_new(%w| JAN FEB ... |)
但这不起作用(至少,不像我希望的那样),因为 const_set 不会在名称为魔法的>的类的上下文中被调用 set(即天和几个月),但显然是在 Class 的上下文中;因此,不仅无法从实例方法访问它,而且每次使用新的名称数组作为参数调用 enum_new 时,它都会被覆盖。使用类变量时会出现类似的问题,因为它们将在使用该方法生成的任何类之间共享(因为它们将成为 Class 的类变量,我猜)。
是否有任何方法可以在使用 Class.new 生成的类中创建常量,从而获得与原始天和月<< / strong>类,不必用几乎相同的类污染我的代码?
感谢您的关注和耐心! :)
答案 0 :(得分:1)
是。在class_exec
块中进行初始化,您可以在其中传递您的名称数据,self
指向正确的类:
theClass=Class.new
theClass.class_exec(names) do |names|
#initialize constants here...
end