I have many (many) instances where I have something like this:
if (let aVar = getVar("var"); aVar != VNULL) {
# do sth
I'm trying to replace this with something more concise (preferrably a macro, which I believe it should work) to avoid all this visual clutter.
E.g.:
if (checkVar("var")) {
# do sth with aVar here
This means that the macro should be able to perform the check and declare the variable with a custom name (a + capitalized var-name, in this case).
This is what I've come up with:
macro checkVar(name: untyped): untyped =
let varName = ident('a' & ($name).capitalizeAscii())
result = quote do:
(let `varName` = getVar(`name`); `varName` != VNULL)
Do you see anything wrong? (It seems to be working, but given that I'm not too familiar with Nim's macros, I'm still not sure...)
You don't need a macro a template works fine, I personally use an operator:
template `?=`(name, value): bool = (let name = value; name != invalidId)
Or if you wanna do it with a macro still, you could do something like this:
macro checkVar(name: untyped, body: untyped): untyped =
let varName = ident('a' & ($name).capitalizeAscii())
result = quote do:
if (let `varName` = getVar(`name`); `varName` != VNULL):
`body`
checkVar("kek"):
# this body is executed only if `getVar` returns something other than VNULL
# aKek is defined in this body
echo aKek
Thanks a lot! I'll give it a try :)
P.S. Χαιρετισμούς από Ισπανία!
Maybe:
import std/[options, macros]
macro someTo(optionValue, varDefOrName: untyped): untyped =
let isVarDef = varDefOrName.kind == nnkVarTy
let varName = if isVarDef: varDefOrName[0] else: varDefOrName
let tempVarName = genSym(nskLet, "temp")
let okVarName = genSym(nskLet, "ok")
result = quote do:
let `okVarName` = `optionValue`.isSome
let `tempVarName` = if `okVarName`: `optionValue`.get else: default(typeof(`optionValue`.get))
when `isVarDef`:
var `varName` {.inject.} = `tempVarName`
else:
let `varName` {.inject.} = `tempVarName`
`okVarName`
# Example usage
var a = "test".some
# when we want var
if a.someTo(var d):
echo "a has a value: ", d
d = "test2"
else:
echo "a is def(T)"
# when we want let
if a.someTo(e):
echo "a has a value: ", e
#e = "test2"
else:
echo "a is def(T)"