Я хочу написать простой Ruby DSL для перевода некоторых операторов и выражений на другой язык. Основной пример будет:перевод блоков и операторов для DSL
some_function {
t + 2
}
Здесь т не является переменным рубином и, таким образом, блок не может (и не должен!) Быть оценен Ruby. Поэтому лучше всего использовать вывод синтаксического анализа (или AST) для самостоятельного перевода. Для этого я могу использовать ParseTree и ruby2ruby. Тем не менее, у меня есть другие конструкции, которые я хотел бы использовать, например:
1.upto(10) {|x|
some_function {
t + x
}
}
Вот, у меня есть локальная переменная, и мне нужно, чтобы получить его значение для того, чтобы сделать свой перевод. Однако в функции, которая выполняет оценку блока, у меня нет доступа к локальным переменным вызывающего блока. Если бы это была глобальная переменная ($ x), я мог бы проверить, существует ли ее имя в массиве global_variables и в худшем случае используется eval, но как я могу сделать это для локальной переменной, если возможно вообще?
Update:
Просто чтобы прояснить вещи. Как я уже сказал, я использую ruby2ruby (и, следовательно, ParseTree), чтобы получить AST (используя to_sexp), соответствующий блоку. Но при использовании локальной переменной внутри моего блока, я сталкиваюсь следующее:
[:dvar, :x]
И таким образом, я должен был бы получить значение переменной от ее имени в качестве строки/символ. И я не могу использовать method_missing или instance_eval, потому что я хочу перевести все выражение на другой язык или синтаксис (например, RPN).
Другое решение, не основанное на ParseTree, будет приветствоваться, тем не менее, поскольку оно, очевидно, не полностью поддерживается Ruby 1.9.
Кстати, ваш проект с открытым исходным кодом? Я работаю над DSL, которому в какой-то момент может понадобиться другой бэкэнд, поэтому эта техника мне интересна. –