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 @isdefined(Symbol(str))
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 :(Symbol(str)), not :abc. A way to get :abc is to evaluate the Symbol then interpolate it into the Expression, :($(Symbol(str))). Slight problem, $-interpolation is something done in :() and 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 hasproperty(@__MODULE__, Symbol(str))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.