2015-07-09 7 views
7

Desidero generare automaticamente alcune funzioni ed esportarle automaticamente. Per avere un esempio concreto, diciamo che voglio costruire un modulo, che fornisce funzioni che prendono un segnale e applicano una media mobile/massima/minima/mediana ... ad essa.Julia genera automaticamente le funzioni ed esportale

La generazione di codice funziona già:

for fun in (:maximum, :minimum, :median, :mean) 
    fname = symbol("$(fun)filter") 
    @eval ($fname)(signal, windowsize) = windowfilter(signal, $fun, windowsize) 
end 

avermi dato Funzioni dell'orologio

maximumfilter 
minimumfilter 
... 

Ma come faccio a esportare automaticamente? per esempio. Vorrei aggiungere un po 'di codice al ciclo precedente come

export $(fname) 

e ogni funzione viene esportata dopo la creazione.

+3

'eval (Espr (: export, fname))' funziona? Io uso qualcosa del genere in 'SymPy'. Non sono sicuro che sia il modo migliore però. – jverzani

+0

Grazie, funziona per me! –

risposta

5

Si potrebbe considerare l'utilizzo di una macro:

module filtersExample 

macro addfilters(funs::Symbol...) 
    e = quote end # start out with a blank quoted expression 
    for fun in funs 
    fname = symbol("$(fun)filter") # create your function name 

    # this next part creates another quoted expression, which are just the 2 statements 
    # we want to add for this function... the export call and the function definition 
    # note: wrap the variable in "esc" when you want to use a value from macro scope. 
    #  If you forget the esc, it will look for a variable named "maximumfilter" in the 
    #  calling scope, which will probably give an error (or worse, will be totally wrong 
    #  and reference the wrong thing) 
    blk = quote 
     export $(esc(fname)) 
     $(esc(fname))(signal, windowsize) = windowfilter(signal, $(esc(fun)), windowsize) 
    end 

    # an "Expr" object is just a tree... do "dump(e)" or "dump(blk)" to see it 
    # the "args" of the blk expression are the export and method definition... we can 
    # just append the vector to the end of the "e" args 
    append!(e.args, blk.args) 
    end 

    # macros return expression objects that get evaluated in the caller's scope 
    e 
end 

windowfilter(signal, fun, windowsize) = println("called from $fun: $signal $windowsize") 

# now when I write this: 
@addfilters maximum minimum 

# it is equivalent to writing: 
# export maximumfilter 
# maximumfilter(signal, windowsize) = windowfilter(signal, maximum, windowsize) 
# export minimumfilter 
# minimumfilter(signal, windowsize) = windowfilter(signal, minimum, windowsize) 

end 

quando lo si carica, vedrete le funzioni vengono esportate automaticamente:

julia> using filtersExample 

julia> maximumfilter(1,2) 
called from maximum: 1 2 

julia> minimumfilter(1,2) 
called from minimum: 1 2 

Vedi the manual per maggiori informazioni.

+0

Per me questo non funziona, ho ottenuto una "sintassi: token extra" ("dopo la fine dell'espressione" sulla riga export $ (esc (fname)). –

+0

Sei su 0.3? Sto usando una versione di sviluppo 0.4 , quindi è possibile/probabile che la sintassi sia cambiata da 0,3 Non ho 0,3 installato ... può aiutare qualcun altro? –

+0

Ah hai ragione, io uso 0.3 in effetti. –