джулия генерирует выражение с символом в нем

#julia #metaprogramming #symbols

Вопрос:

Мне нужно сгенерировать call выражение, в котором одним из аргументов ключевого слова является символ. Я могу ввести это явно так:

 juliagt; dump(:(func(something; a=:b))) Expr  head: Symbol call  args: Array{Any}((3,))  1: Symbol func  2: Expr  head: Symbol parameters  args: Array{Any}((1,))  1: Expr  head: Symbol kw  args: Array{Any}((2,))  1: Symbol a  2: QuoteNode  value: Symbol b  3: Symbol something   

Обратите внимание на аргумент ключевого a слова, который имеет значение symbol :b

Что я хочу сделать, так это сгенерировать это выражение программно, где :b деталь интерполируется, скажем, из некоторой переменной x .

Я попробовал это

 juliagt; x = :u :u  juliagt; dump(:(func(something; a=$(x)))) Expr  head: Symbol call  args: Array{Any}((3,))  1: Symbol func  2: Expr  head: Symbol parameters  args: Array{Any}((1,))  1: Expr  head: Symbol kw  args: Array{Any}((2,))  1: Symbol a  2: Symbol u  3: Symbol something   

но вместо того, чтобы получить значение a QuoteNode со значением Symbol u , я просто получаю символ u. Это не сработает, потому что, когда я оцениваю выражение, оно ищет переменную u , но должно просто вставлять Symbol u ее . Я пробовал кое — что другое, но не могу заставить это работать. Спасибо

Комментарии:

1. Просто заверните его в QuoteNode или используйте Meta.quot : :(func(something; a=$(QuoteNode(x)))) .

2. @pfitzseb Сделайте это ответом, единственное, что я бы добавил, — это показать результат dump( :(a :u) ) vs dump( :(a u) ) , чтобы проиллюстрировать разницу.

3. @dantheman Я также отмечу, что интерполяция :(a $x) идентична Expr(:call, : , :a, x) . Таким образом, вы вставляете Символ :u в выражение, он просто обрабатывается как переменная во время вычисления, как и все остальные символы. Поэтому, чтобы сохранить его в качестве символа при оценке, вам просто нужно было завернуть его в QuoteNode. Остерегайтесь этих интуитивных способов обертывания: :($x) , $(:x) , и :x ; они могут показаться правильными, но dump покажут, что вы вставляете символ :x , а не :u .

4. @pfitzseb Да, это сработало. Я мог бы поклясться, что пытался это сделать, но, думаю, нет. Спасибо

Ответ №1:

Вы можете обернуть x QuoteNode вручную или использовать Meta.quot (что создает Expr(:quote, ...) ):

 juliagt; x = :u;  juliagt; dump(:(func(something; a=$(QuoteNode(x))))) Expr  head: Symbol call  args: Array{Any}((3,))  1: Symbol func  2: Expr  head: Symbol parameters  args: Array{Any}((1,))  1: Expr  head: Symbol kw  args: Array{Any}((2,))  1: Symbol a  2: QuoteNode  value: Symbol u  3: Symbol something  juliagt; func(x; a) = x, a func (generic function with 1 method)  juliagt; eval(:(func(something; a=$(QuoteNode(x))))) (something, :u)  juliagt; eval(:(func(something; a=$(Meta.quot(x))))) (something, :u)