Hello!
I am trying to make a macro, @each, which will take each value and compare the falsehood of it to a certain condition. The problem is, while it works fine so long as the macro is globally defined, i.e. in a notebook:
macro each(exp::Expr)
x = exp.args[2]
if length(exp.args) == 2
for value in eval(x)
state = eval(Meta.parse(string(exp.args[1], "(", value, ")")))
if state != true
return(false)
end
end
end
for value in eval(x)
state = eval(Meta.parse(string(value," ", exp.args[1], " ", exp.args[3])))
if state != true
return(false)
end
end
return(true)
end
I am not so sure that the function version is entirely working (yet,) though it might be. Here is that macro now working:
if @each [5, 10, 15] >= 5
print("hi")
end
hi
if @each [5, 10, 15] > 50
println("This will not print")
end
x = [5, 5]
# Yes I know, we have .==, but we don't have
# .ismissing(), and things like that.
if @each x == 5
println("Yes.")
end
Yes.
The only issue comes when I want to evaluate something like the last expression after including a module to do so.
include("src/Each.jl")
if Main.Each.@each x < 20
end
LoadError: UndefVarError: x not defined
in expression starting at In[4]:1
Of course, providing values still works:
if Main.Each.@each [5, 10, 15] < 20
println("yeah")
end
I noticed that macro definitions by default receive a module, i.e. main under the alias module, pretend that has two __s on either side, as the formatting is… Actually:
__module__
Thank goodness for method errors for telling me that, by the way. Anyway, I was just wondering if there is some sort of way I can evaluate this module into here. As you can see, evaluating a string Main.x yield x:
eval(Meta.parse("Main.x"))
3-element Vector{Int64}:
5
10
15
But for some reason, evaluating Main.x does not really do anything… Additionally, it would be nice to keep them as symbols.