如何获取Julia宏的方法?

6
在Julia中,methods函数可用于检索函数的方法。
julia> f(::Int) = 0
f (generic function with 1 method)

julia> f(::String) = ""
f (generic function with 2 methods)

julia> methods(f)
# 2 methods for generic function "f":
f(::String) in Main at REPL[1]:1
f(::Int64) in Main at REPL[0]:1

宏也可以有多个方法。
julia> macro g(::Int)
           0
       end
@g (macro with 1 method)

julia> macro g(::String)
           ""
       end
@g (macro with 2 methods)

julia> @g 123
0

julia> @g "abc"
""

然而,methods函数似乎无法用于宏,因为Julia首先调用宏,这是因为宏不需要括号。
julia> methods(@g)
ERROR: MethodError: no method matching @g()
Closest candidates are:
  @g(::String) at REPL[2]:2
  @g(::Int64) at REPL[1]:2

我尝试使用一个表达式来包含宏,但这并没有起作用。
julia> methods(:@g)
# 0 methods for generic function "(::Expr)":

如何检索宏的方法?


1
methods(eval(Symbol("@g"))) 对我来说可行,但一定有更简洁的方法。 - Dan Getz
3
清除器(无“eval”):methods(Main.(Symbol("@g"))) - Dan Getz
4
不错。但是确实应该有一种更清晰的方法......(顺便说一下,Main.(Symbol("@g"))已经被弃用了,应该使用getfield(Main, Symbol("@g"))代替。) - Harrison Grodin
1个回答

2

我会在~/.juliarc.jl中创建一个模块(MethodsMacro),并将一个通用宏(@methods)放入其中,同时加上一行代码:using MethodsMacro。这样你就可以在每个Julia会话中使用它,类似于:

julia> module MethodsMacro                                               

       export @methods                                              

       macro methods(arg::Expr)                                     
           arg.head == :macrocall || error("expected macro name")   
           name = arg.args[] |> Meta.quot                           
           :(methods(eval($name)))                                  
       end                                                          

       macro methods(arg::Symbol)                                   
           :(methods($arg)) |> esc                                  
       end                                                          

       end                                                          
MethodsMacro                                                             

julia> using MethodsMacro                                                

julia> @methods @methods                                            
# 2 methods for macro "@methods":                                   
@methods(arg::Symbol) at REPL[48]:12                                
@methods(arg::Expr) at REPL[48]:6                                   

julia> f() = :foo; f(x) = :bar                                      
f (generic function with 2 methods)                                 

julia> @methods f                                                   
# 2 methods for generic function "f":                               
f() at REPL[51]:1                                                   
f(x) at REPL[51]:1     

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接