基本上,我想象一些看起来像这样的伪代码
build_command_list {
add_command("cmd 1")
add_command("cmd 2")
conditional_branch( some_cond ) {
add_command("cmd3")
add_command("cmd4")
}
conditional_branch( some_other_cond ) {
add_command("cmd 5")
}
}
方法build_command_list
将采用一段代码,然后递归地构建一个树结构,其中每个节点都是一个命令,一些解释器将从该根获取该树并执行它,这是第一个命令那段代码(在这种情况下,"cmd 1"
)
add_command
和conditional_branch
是确定如何创建节点的其他方法。
有conditional branch
这样的命令告诉解释器评估一个条件,如果是,它将处理它的命令列表。
我想知道ruby是否有一些东西可以让我像上面的例子一样编写一段代码,然后拿出代码并解析它?
如果没有,也许有人可以建议我以这样的方式编写输入,以便我可以从一组命令构建正确的命令树?
答案 0 :(得分:2)
您可以编写完全符合此要求的DSL:
class CommandList
def add_command(str)
puts "Adding command #{str}"
end
def conditional_branch(condition, &block)
b = ConditionalBranch.new(condition)
puts "With condition: #{condition} {"
b.instance_eval(&block)
puts "}"
end
end
class ConditionalBranch < CommandList
def initialize condition
@condition = condition
end
end
def build_command_list &block
c = CommandList.new
c.instance_eval(&block)
end
build_command_list {
add_command("cmd 1")
add_command("cmd 2")
conditional_branch( "some_cond" ) {
add_command("cmd3")
add_command("cmd4")
}
conditional_branch( "some_other_cond" ) {
add_command("cmd 5")
}
}
Adding command cmd 1
Adding command cmd 2
With condition: some_cond {
Adding command cmd3
Adding command cmd4
}
With condition: some_other_cond {
Adding command cmd 5
}
请注意,这可能不会按照您希望的方式处理条件,它只是一个示例,说明如何使用instance_eval来评估给定对象上下文中的块
答案 1 :(得分:0)
你在这里谈论的是一种DSL(领域特定语言)。
您可以在ruby中实现内部和外部DSL。
对于外部DSL,您需要创建一个解析器。这就是为什么用ruby创建内部DSL通常会更好。
我写了一篇关于可用于实现此目的的基本技术的博客文章:http://blog.nofail.de/2010/02/writing-your-own-dsl-with-ruby/