Lit*_*les 26 ruby dsl metaprogramming metaclass
我正在用Ruby编写内部DSL.为此,我需要以编程方式创建命名类和嵌套类.这样做的最佳方法是什么?我认为有两种方法可以做到这一点:
Class.new创建一个匿名类,然后使用define_method的方法添加到它,最后调用const_set将其添加为命名常量一些命名空间.eval我已经测试了第一种方式并且它有效,但是对Ruby来说是新手,我不确定将类作为常量是正确的方法.
还有其他更好的方法吗?如果没有,上述哪一项更可取?
Dyl*_*kes 27
如果您想创建一个具有动态名称的类,您将必须完全按照您的说法进行操作.但是,您不需要使用define_method.您可以将块传递给Class.new初始化类的块.这在语义上与class/ 的内容相同end.
记住const_set,要认真对待self那个范围内的接收者().如果你想要全局定义的类,你需要调用const_setTopLevel模块(它的名称和细节因Ruby而异).
a_new_class = Class.new(Object) do
attr_accessor :x
def initialize(x)
print #{self.class} initialized with #{x}"
@x = x
end
end
SomeModule.const_set("ClassName", a_new_class)
c = ClassName.new(10)
...
Run Code Online (Sandbox Code Playgroud)
你真的不需要使用const_set.返回值Class.new可以分配给常量而块Class.new是class_eval.
class Ancestor; end
SomeClass = Class.new(Ancestor) do
def initialize(var)
print "#{self.class} initialized with #{var}"
end
end
=> SomeClass
SomeClass.new("foo")
# SomeClass initialized with foo=> #<SomeClass:0x668b68>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11772 次 |
| 最近记录: |