Pre-face: I know that this is properly not the smartest thing to do, if it is even possible. I want to learn and test something out.
I was thinking if I could do something like this, imagine by using a macro:
@var2str VariableName
VariableName = "VariableName"
The reason I want to do this is because I am playing with EzXML.jl and I would like to be able to do something like this:
@var2xmlelement VariableName
VariableName = ElementNode("VariableName")
Kind regards
You can. This works … it is scruffy.
macro var2string(var)
:($(esc(var)) = $(String(var)))
end
julia> @var2string VariableName
"VariableName"
julia> VariableName
"VariableName"
To really match your example, return nothing
from the macro.
That macro is taken from @simeonschaub:
macro var2string(var)
:($(esc(var)) = ElementNode($(String(var))))
end
4 Likes
Thanks that indeed works!
For EzXML I did like this:
macro var2xmlelement(var)
eval(Meta.parse("$(var) = ElementNode(\"$(var)\")"))
end
You mention it is scruffy, would you care to elaborate a bit?
I guess the more conventional way would be to write everything out or use dicts, is perhaps what you mean?
I marked your answer as solution since it does what I asked for, thanks.
Kind regards
1 Like
It ignores macro hygene. I might just write them all out (and probably use a separate file for that, if there are many).
2 Likes
Thanks for the link!
I have read through the hygiene section and think I caught the gist of it, which is that if not using the macro carefully I might overwrite or modify already predefined variables. So this is something I would have to bare careful about.
If there is a smarter way to do the macro I am of course open to it.
Kind regards
Macro hygiene doesn’t really apply, since the goal of your macro is to overwrite a variable.
Maybe – unless, as I had read the request, to be about creating new variables where overwriting would be unintended and unwanted.
2 Likes
Don’t do it like this. There is never a good reason for calling eval
inside a macro and manipulating expressions as strings and reparsing afterwards is also a code smell, which can easily break if used with non-standard variable names. Instead, you can just write this as:
macro var2string(var)
:($(esc(var)) = ElementNode($(String(var))))
end
6 Likes
thanks
@Ahmed_Salih listen to @simeonschaub
I am replacing my original macro with his (with attribution).
Thanks @JeffreySarnoff and @simeonschaub !
I will use Simeon’s way going forward. The last question I have for now is if it is possible to make the macro work on an array of strings or something similar?
For example I had the three variables; a,b,c I would now have to do:
@var2string(a)
@var2string(b)
@var2string(c)
But it would be nice if I could do something akin to (syntax does not work!):
@. @var2string a,b,c
Or maybe instead of writing a,b,c directly, I could use [“a”,“b”,“c”] as what the macro should work on, which would be fine as well.
Kind regards
using EzXML
macro var2node(var)
:($(esc(var)) = ElementNode($(String(var))))
end
# foreach_helper rom @pdeffenbach
# https://discourse.julialang.org/t/foreach-for-macros/57678/2?u=jeffreysarnoff
function foreach_helper(x)
macroname = x.args[1]
macroargs = x.args[3:end]
result = quote end
for arg in macroargs
result = quote
$result
$(Expr(:macrocall, macroname, LineNumberNode(0), arg))
end
end
return result
end
macro foreach(x)
foreach_helper(x)
end
@foreach(@var2node(
Element, Attribute, Document
));
julia> typeof.((Element, Attribute, Document))
(EzXML.Node, EzXML.Node, EzXML.Node)
julia> Element != Attribute != Document
true
1 Like
Thanks! That works.
Sorry for asking a lot, but I always feel I get one step closer, to hit a point where I struggle to move on. Using the function you altered to my needs I can now do:
@foreach(@var2xmlelement(a,b,c));
Which does exactly what I want, it produces three variables; a, b and c, which are element nodes as I wish them to be.
Suppose I want to make it so that an user can specify an input say again of three variables; d, e and f. Then my code should generate the element nodes and output these variables as such:
function give_variables(variableArray) #I want it to be able to accept any size of input, for now d e f only
@foreach(@var2xmlelement(variableArray));
end
Should I use symbols or string arrays instead? Do you think it is possible to do what I want?
One user might want variableArray to be d,e,f another one might only want d,e etc. That is why I need it to be controllable.
Kind regards
… without knowing how to make your last intent work comfortably
… I defer to others.
1 Like
No problem at all, thank you very much for having taking time to help me out, I really learned a new aspect about Julia I had not delved that much into before!
Kind regards