Given a variable that is a string. For example:
str = “abc”
I would like to check if the variable corresponding to the string (in this case
abc) is defined. I tried
but this generates an error:
ERROR: LoadError: MethodError: no method matching var"@isdefined"(::LineNumberNode, ::Module, ::Expr)
Closest candidates are:
var"@isdefined"(::LineNumberNode, ::Module, ::Symbol)
@ Base essentials.jl:191
What is the right way to do what I want? – Thanks.
Being a macro,
@isdefined is operating on the following source code as an
Expression, in other words it’s seeing
:abc. A way to get
:abc is to evaluate the Symbol then interpolate it into the
:($(Symbol(str))). Slight problem,
$-interpolation is something done in
quote end runtime expressions, and few macros implement that for source code.
@isdefined doesn’t, so you have to use a macro that does
@eval @isdefined $(Symbol(str)). Macros are expanded at parsing of source code, so
str must have a value by that point. As a consequence, interpolating macros like
@eval only work in the global scope, not local scopes like function bodies that have not run and assign
str yet. Since
@eval only works in global scopes anyway, you could instead use the function call
isdefined(@__MODULE__, Symbol(str)) (if you declared
global abc without assigning it,
hasproperty returns true but
isdefined returns false).
Also discourse formatting tip, use backticks ` to surround a line of code and triple-backticks ``` to surround a block of code.
Use the function instead of the macro:
str = "abc"
Note that you will need to also pass the module in which the symbol should be looked up.
Thanks! This works. For me I use