2014-09-27 5 views
6

ich this question mit metaprogramming, aber die Scoping-Regeln für Schleifen beantworten will verursachen meine Variablen nicht in dem oberen meist (REPL) Umfang definiert werden:Deklarieren von Top-Level-Variablen in Julia mit metaprogramming

for x = [:A1, :A2] 
    @eval x = rand(2,2) 
end 

Ich weiß, dass es wahrscheinlich einen einfachen Weg gibt, aber mein Freitag Nacht Gehirn kann nicht an einen denken. Kann einer von euch metaprogrammierenden Junkies mir helfen, eine prägnante Lösung zu finden? (Ich weiß, ein Makro mit Flucht funktionieren könnte, aber ich versuche, an etwas zu denken kürzer)

+0

Ich sah das auch und fragte mich, wie Sie es metaprogram würden, wenn Sie hundert A hatten. 'für x = 1: 100' und was dann? Wie können Variablennamen programmgesteuert erstellt werden? – rickhg12hs

+1

Beantwortete meinen eigenen Kommentar/Frage. 'für k = 1: 10 my_sym = symbol (" A "* string (k)); @eval $ my_sym = rand (2,2) end' (Hier wird A1 bis A10 generiert.) – rickhg12hs

Antwort

7

Wenn Sie nur die Variablen im globalen Bereich zu definieren, Sie fehlt nur ein $:

for x = [:A1, :A2] 
    @eval $x = rand(2,2) 
end 

Aber @eval wird immer auf höchster Ebene ausgewertet, auch wenn Sie es in eine Funktion einfügen. Wenn Sie die Variablen in einem Funktionsumfang definieren wollen, müssen Sie die gesamte Funktion innerhalb @eval setzen, den Codeblock zu konstruieren und zu interpolieren sie in die Funktion:

@eval function f() 
    ... 
    $([:($x = rand(2, 2)) for x in [:A1, :A2]]...) 
    ... 
end 

Dieser Code kann auch triviale Weise in eine angepasst werden Makro (aber dann braucht es esc).

+0

Ahh, danke. Für dein zweites Beispiel habe ich eine gekürzte Version ausprobiert, habe aber: julia> @eval $ ([: ($ x = rand (2,2)) für x in [: B1,: B2]] ...) FEHLER: type: apply_type: in Vararg, erwarteter Typ {T <: Top}, erhaltener Array {Expr, 1} – JKnight

+0

Scheint, dass du @eval begin $ ([: ($ x = rand (2,2)) für x in [ : B1,: B2]] ...) end 'oder 'eval (Ausdruck (: block, [: ($ x = rand (2,2)) für x in [: B1,: B2]] ...)) 'damit das funktioniert. Aber ich bin mir nicht sicher, dass es viel Sinn macht, da das die Variablen immer noch auf globaler Ebene definieren wird, auch wenn Sie es in eine Funktion einfügen, und wenn Sie das denken, sieht mein erstes Beispiel etwas netter aus. – simonster