我有一个引用的表达式,例如:
ast = quote do
IO.puts x
end
我希望在表达式中注入一个变量,以便x有一个值,并且由于CompileError
被定义为x
时表达式不会引发Code.eval_quoted ast, [x: "Hello, world!"]
,如下所示:
ast = quote do
x = var!(x)
IO.puts x
end
这个AST传递给我,我无法更改它生成的代码。我通过后可以修改AST。
我想这样做我可以将AST转换为类似于引用的表达式:
{:__block__, [],
[{:=, [],
[{:x, [], Elixir}, {:var!, [context: Check.Runner], [{:x, [], Elixir}]}]},
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
[{:x, [], Check.RunnerTest}]}]}
尝试此操作后,我的AST看起来像这样:
var!
这不起作用。我认为这可能是因为{:__block__, [],
[{:=, [],
[{:x, [], Check.RunnerTest},
{:var!, [context: Check.Runner], [{:x, [], Check.Runner}]}]},
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
[{:x, [], Check.RunnerTest}]}]}
的上下文值不正确。
解决方案:我现在意识到变量的范围不正确,我需要这样的AST:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var oldValue, newValue;
if(mutation.type === 'characterData' &&
mutation.target.parentNode &&
mutation.target.parentNode.nodeName.toLowerCase() === 'p')
{
oldValue = mutation.oldValue;
newValue = mutation.target.textContent;
} else if(mutation.target.nodeName.toLowerCase() === 'p' &&
mutation.addedNodes.length &&
mutation.removedNodes.length)
{
oldValue = mutation.removedNodes[0].textContent;
newValue = mutation.addedNodes[0].textContent;
} else {
return;
}
// do stuff
document.write('old: ' + oldValue + ', new: ' + newValue);
});
});
observer.observe(document.body, { characterDataOldValue: true, subtree: true, childList: true, characterData: true });
// test
document.querySelector('p').textContent = 'good bye';
答案 0 :(得分:2)
您的代码应该正常工作。事实上,你写了:
ast = quote do
x = var!(x)
IO.puts x
end
但是您展示了其他一些代码的AST,其中一个代码是您将1
分配给var!(x)
的代码。换句话说,上面的代码没有任何问题。