我想编写一个简单的 Ruby DSL 来将一些语句和表达式翻译成另一种语言。一个基本的例子是:
some_function {
t + 2
}
在这里, t 不是 ruby 变量,因此块不能(也不能!)由 Ruby 评估。所以我最好的选择是使用解析输出(或 AST)自己进行翻译。为此,我可以使用 ParseTree 和 ruby2ruby。但是,我还有其他想要使用的构造,例如:
1.upto(10) {|x|
some_function {
t + x
}
}
在这里,我有一个局部变量,我需要获取它的值才能进行翻译。但是,在执行块评估的函数中,我无权访问调用块的局部变量。如果它是一个全局变量 ($x),我可以检查它的名称是否存在于 global_variables 数组中,并且在最坏的情况下使用 eval,但是如果可能的话,我怎么能对局部变量这样做呢?
更新:
只是为了收拾东西。就像我最初说的那样,我使用 ruby2ruby(以及因此 ParseTree)来获取与块对应的 AST(使用 to_sexp)。但是在我的块中使用局部变量时,我遇到以下情况:
[:dvar, :x]
因此,我需要从变量的名称中获取变量的值作为字符串/符号。而且我不能使用 method_missing 或 instance_eval,因为我想将整个表达式翻译成另一种语言或语法(如 RPN)。
尽管如此,另一种不基于 ParseTree 的解决方案仍将受到欢迎,因为 Ruby 1.9 显然不完全支持它。