2015-09-06 2 views
3

У меня есть цитируемое выражение, как это:инъекционных переменные в кавычках выражение

ast = quote do 
    IO.puts x 
end 

И я хочу, чтобы ввести переменную в выражение, так что х имеет значение, а выражение не повысится CompileError из-за x быть неопределенным, когда оценивается так:

Code.eval_quoted ast, [x: "Hello, world!"] 

Эта AST передается мне, и я не могу изменить код он генерируется с. Я могу изменить AST после того, как я его передал.

Я думал сделать это, я мог бы преобразовать АСТА походить цитируемое выражение:

ast = quote do 
    x = var!(x) 
    IO.puts x 
end 

После попытки это мой АСТ выглядит так:

{:__block__, [], 
[{:=, [], 
    [{:x, [], Elixir}, {:var!, [context: Check.Runner], [{:x, [], Elixir}]}]}, 
    {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], 
    [{:x, [], Check.RunnerTest}]}]} 

Это не работает. Я думал, что это может быть связано с неправильным значением для контекста var!.

Разрешение: теперь я понимаю, что переменные были в неправильном объеме, и мне нужно AST, как это:

{:__block__, [], 
[{:=, [], 
    [{:x, [], Check.RunnerTest}, 
    {:var!, [context: Check.Runner], [{:x, [], Check.Runner}]}]}, 
    {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], 
    [{:x, [], Check.RunnerTest}]}]} 

ответ

2

Ваш код должен просто работать. На самом деле, вы писали:

ast = quote do 
    x = var!(x) 
    IO.puts x 
end 

Но вы показали AST для какого-то другого кода, тот, где вы назначили 1 к var!(x). Другими словами, нет ничего плохого в коде выше.

+0

Ах, я вставил в неправильный. После прочтения вашего комментария ниже я понимаю, что у меня была переменная в неправильной области из-за установки неправильного контекста. Я обновил вопрос выше. – lpil

+1

Теперь, когда вы обновили вопрос, сам вопрос неправильный (пример действительно работает), и этот ответ несколько ошибочен. : P –

+0

Yup. Это все беспорядок. Наверное, лучше уйти сейчас! – lpil

Смежные вопросы