2015-07-09 14 views
7

Chcę automatycznie generować niektóre funkcje i eksportować je automatycznie. Aby mieć konkretny przykład, powiedzmy, że chcę zbudować moduł, który zapewnia funkcje, które pobierają sygnał i stosują do niego średnią ruchomą/maksymalną/minimalną/medianę.Julia automatycznie generuje funkcje i eksportuje je

Generowanie kodu już działa:

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

dając mi działa

maximumfilter 
minimumfilter 
... 

Ale jak mogę eksportować je automatycznie? na przykład Chciałbym dodać trochę kodu do powyższej pętli, jak

export $(fname) 

i po wyeksportowaniu każdej funkcji.

+3

Czy "eval (Expr (: export, fname))" działa? Używam czegoś takiego w 'SymPy'. Nie jestem pewien, czy to najlepszy sposób. – jverzani

+0

Dziękuję, to działa dla mnie! –

Odpowiedz

5

Można by rozważyć użycie makra:

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 

podczas ładowania go, zobaczysz funkcje są automatycznie eksportowane:

julia> using filtersExample 

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

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

Zobacz the manual aby uzyskać więcej informacji.

+0

Dla mnie to nie działa, mam "składnia: dodatkowy token" ("po zakończeniu wyrażenia" przy eksporcie linii $ (esc (fname)). –

+0

Czy jesteś na 0.3? Używam wersji rozwojowej 0.4 , więc jest możliwe/prawdopodobne, że składnia zmieniła się od 0.3. Nie mam zainstalowanego 0.3 ... czy ktoś inny może pomóc? –

+0

Ach masz rację, używam 0.3. –