我想从作为参数传递的本地函数(如doSomething(fn a -> a * 10 end)
)获取AST
所以我试着
def test do
inspectAST(fn a,b -> a + b + 42 end)
inspectAST(quote do: fn a,b -> a + b + 42 end)
inspectFunctionInfo(fn a,b -> a + b + 42 end)
:ok
end
def inspectAST(this_is_AST) do
IO.inspect(this_is_AST)
IO.inspect("--------------------------------")
end
def inspectFunctionInfo(fun) do
IO.inspect(Function.info(fun))
IO.inspect("--------------------------------")
end
结果:
iex(3)> Utils.test
#Function<0.30424669/2 in Utils.test/0>
"--------------------------------"
{:fn, [],
[
{:->, [],
[
[{:a, [], Utils}, {:b, [], Utils}],
{:+, [context: Utils, import: Kernel],
[
{:+, [context: Utils, import: Kernel],
[{:a, [], Utils}, {:b, [], Utils}]},
42
]}
]}
]}
"--------------------------------"
[
pid: #PID<0.485.0>,
module: Utils,
new_index: 1,
new_uniq: <<58, 7, 203, 172, 99, 108, 54, 80, 24, 151, 75, 56, 73, 174, 138,
177>>,
index: 1,
uniq: 30424669,
name: :"-test/0-fun-1-",
arity: 2,
env: [],
type: :local
]
"--------------------------------"
我想要的是inspectAST(quote do: fn a,b -> a + b + 42 end)
(AST)的结果,但我想发送类似inspectAST(fn a,b -> a + b + 42 end)
的函数,而不发送quote do:
如果有人对此有一些想法,你的帮助将非常感激:)
1条答案
按热度按时间hgb9j2n61#
If you want a "function" to be called on the AST, not values, it should be a macro, not a function.
The following should be a good base for what you want to achieve:
defmacro
to treat your parameter as AST, not a regular valueIO.inspect
to happen at runtime, not compile time, so we need to return the AST for it usingquote
ast
variable, so we are usingunquote
unquote
will unescapeast
as well, so we need to escape it once more usingMacro.escape/2
Please note that the macro should be defined before calling it, so
defmacro
has to be beforetest
, not after.For more advanced explanations about macros, you should check this serie of articles which is very detailed.