Can I use a function variable name to generate a string to set it equal to?

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 :slight_smile:
@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! :blush:

Kind regards