我正在尝试编写一个DSL,它允许我这样做
Policy.name do
author "Foo"
reviewed_by "Bar"
end下面的代码几乎可以处理它:
class Policy
include Singleton
def self.method_missing(name,&block)
puts name
puts "#{yield}"
end
def self.author(name)
puts name
end
def self.reviewed_by(name)
puts name
end
end将我的方法定义为类方法(self.method_name),我可以使用以下语法访问它:
Policy.name do
Policy.author "Foo"
Policy.reviewed_by "Bar"
end如果我从方法名中删除"self“,并尝试使用我想要的语法,那么我在Main中收到一个错误"Method not find”,因此它在模块内核之前找不到我的函数。没关系,我理解这个错误。但是我怎么才能修复它呢?我如何修复我的类,使其与我想要的语法一起工作?
发布于 2010-05-30 01:17:36
为了控制块范围内的self (因为author解析为self.author),您可以使用instance_eval。
class Policy
def self.name(&block)
PolicyNameScope.new(block)
end
class PolicyNameScope
def initialize(block)
instance_eval(&block)
end
def author(author)
@author = author
end
def reviewed_by(reviewed_by)
@reviewed_by = reviewed_by
end
end
end
policy = Policy.name do
author "Dawg"
reviewed_by "Dude"
end
p policy
# => #<Policy::PolicyNameScope:0x7fb81ef9f910 @reviewed_by="Dude", @author="Dawg">PolicyNameScope类具有name块中允许的实例方法。这是因为来自Policy的方法在块中不可用,这使得领域特定语言变得更加紧凑。
由于您的示例脱离了上下文,因此我不能进一步帮助您--这段代码本身似乎没有多大用处。
发布于 2010-07-13 16:38:02
上面由奥古斯特提出的答案是正确的,但是如果你想将你的构造器用于其他目的,那么上面的方法就失败了。因此,在这种情况下,您必须使用除上述方法之外的其他方法。这是我在不使用类构造函数的情况下准备的解决方案。
class Policy
def self.method_missing(name,&block)
self.class_eval(&block)
end
def self.author(name)
p name
end
def self.reviewed_by(name)
p name
end
end
Policy.name do
author "Foo"
reviewed_by "Bar"
end这不是一个优化的解决方案,而是你所说的问题的解决方案。
https://stackoverflow.com/questions/2935894
复制相似问题