2014-09-27 1 views
6

Я хочу ответить this question с помощью метапрограммирования, но правила определения объема для петель вызывают мои переменные не могут быть определены в самой верхней (REPL) Область применения:Объявление переменных верхнего уровня в Джулию, используя метапрограммирование

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

Я знаю, что есть, вероятно, простой способ обойти это, но мой мозг в пятницу ночью не может думать об одном. Может ли один из вас метапрограммировать наркоманов помочь мне найти сжатое решение? (Я понимаю, что макрос может работать с побега, но я стараюсь думать о чем-то более короткой)

+0

Я тоже видел это и задавался вопросом, как вы метапрограммируете его, если у вас есть сотня А. 'для x = 1: 100', а затем что? Как можно программировать имена переменных? – rickhg12hs

+1

Отвечал на собственный комментарий/вопрос. 'для k = 1: 10 my_sym = символ (« A »* string (k)); @eval $ my_sym = rand (2,2) end' (показано здесь, генерируя от A1 до A10.) – rickhg12hs

ответ

7

Если вы хотите, чтобы определить переменные в глобальной области видимости, вы просто отсутствует $:

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

Но @eval всегда оценивается на верхнем уровне, даже если вы положили его внутри функции. Если вы хотите, чтобы определить переменные в области видимости функции, вы должны поместить все функции внутри @eval, построить блок кода, и интерполировать его в функцию:

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

Этот код также может быть тривиальным адаптированной в макрос (но тогда он нужен esc).

+0

Ahh, спасибо. для второго примера я попробовал сокращенную версию, но получил: julia> @eval $ ([: ($ x = rand (2,2)) для x в [: B1,: B2]] ...) ОШИБКА: type: apply_type: в Vararg, ожидаемый тип {T <: Top}, получил Array {Expr, 1} – JKnight

+0

Кажется, вам нужно '@eval begin $ ([: ($ x = rand (2,2)) для x в [ : B1,: B2]] ...) end' или 'eval (Expr (: block, [: ($ x = rand (2,2)) для x в [: B1,: B2]] ...)) 'для этого работать. Но я не уверен, что есть много смысла, так как это все равно определит переменные в глобальной области охвата, даже если вы поместите их внутри функции, и если это то, что вы после того, как я думаю, что мой первый пример выглядит немного лучше. – simonster