我正在尝试创建一个新类,而不知道该类的名称,直到它被创建为止。
像这样的东西;
variable = "ValidClassName"
class variable
end
Test = ValidClassName.new
如果可能的话,我也会欣赏有关如何动态地向这个新类添加属性(和方法)的提示。
我将为课程检索“设置”,它们看起来像这样:
title :Person
attribute :name, String
attribute :age, Fixnum
但不应将其设计为仅接受该显式文件,这些属性的数字结尾类型可能不同。
最终会产生一个看起来像这样的类:
class Person
def initialize(name, age)
@name_out = name
@age_out = age
end
end
帮助?
答案 0 :(得分:27)
类在分配给常量时获得其名称。因此,使用const_set
以通用方式进行操作很容易。
例如,假设您想使用Struct
构建具有某些属性的类,您可以:
name = "Person"
attributes = [:name, :age]
klass = Object.const_set name, Struct.new(*attributes)
# Now use klass or Person or const_get(name) to refer to your class:
Person.new("John Doe", 42) # => #<struct Person name="John Doe", age=42>
要从其他类继承,请将Struct.new
替换为Class.new(MyBaseClass)
,例如:
class MyBaseClass; end
klass = Class.new(MyBaseClass) do
ATTRIBUTES = attributes
attr_accessor *ATTRIBUTES
def initialize(*args)
raise ArgumentError, "Too many arguments" if args.size > ATTRIBUTES.size
ATTRIBUTES.zip(args) do |attr, val|
send "#{attr}=", val
end
end
end
Object.const_set name, klass
Person.new("John Doe", 42) # => #<Person:0x007f934a975830 @name="John Doe", @age=42>
答案 1 :(得分:8)
您的代码看起来与此类似:
variable = "SomeClassName"
klass = Class.new(ParentClass)
# ...maybe evaluate some code in the context of the new, anonymous class
klass.class_eval { }
# ...or define some methods
klass.send(:title, :Person)
klass.send(:attribute, :name, String)
# Finally, name that class!
ParentClass.send(:const_set, variable, klass)
...或者您可以使用eval:
eval <<DYNAMIC
class #{name}
title :Person
attribute :name, String
# ...or substitute other stuff in here.
end
DYNAMIC