2017-03-27 95 views
5

Julia'da, methods işlevi, bir işlev yöntemlerini almak için kullanılabilir.Julia makrosunun yöntemlerini nasıl edinebilirim?

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 

Makrolar ayrıca birden çok yöntem içerebilir.

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" 
"" 

Ancak methods fonksiyon Julia ilk dolayı onlar parantez gerekmez olması nedeniyle, makro çağırır çünkü makrolar üzerinde çalışmak için görünmüyor.

julia> methods(@g) 
ERROR: MethodError: no method matching @g() 
Closest candidates are: 
    @g(::String) at REPL[2]:2 
    @g(::Int64) at REPL[1]:2 

Ben makro içerecek bir Expr Ession kullanarak çalıştı, ancak bu işe yaramadı.

julia> methods(:@g) 
# 0 methods for generic function "(::Expr)": 

Makro yöntemlerini nasıl alabilirim?

+1

'yöntemleri (eval (Sembol ("@ g")))' benim için çalıştı, ama daha temiz bir yöntem olmalıdır –

+3

Temizleyici ('eval' olmadan): 'yöntemleri (Ana. (Symbol (" @ g "))) –

+4

@DanGetz Nice. Ama evet, * daha temiz bir metot olmalı * (Bu arada, “Ana.” (Symbol ("@ g")), "anlamsız ve" getfield (Main, Symbol ("@ g")) yerine kullan.) –

cevap

1

Ben hat ile birlikte benim ~/.juliarc.jl bir modül (MethodsMacro) içindeki genel makro (@methods) koyardı: using MethodsMacro. Eğer her Julia oturumu kullanılabilir olurdu Bu şekilde, böyle bir şey:

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