This is simply caused by template hygiene. In case `values` was defined in the
scope you called `runWithBody` it would throw an error if `values` got
redefined there. The solution is to mark `values` as injected, that was Nim
makes it visible to the `body` port of your code:
var callback: proc(args: varargs[int]): string # this line shouldn't change
template runWithBody(minLength: int, body: untyped) =
proc localFunc(values {.inject.}: openArray[int]): string =
if values.len >= minLength:
body
else:
raise newException(ServerException, "Called function contains less
than " & $minLength & " arguments")
callback = proc(args: varargs[int]): string =
localFunc(args)
runWithBody(2):
result = $(values[0] + values[1]) # here is the problem: Error:
undeclared identifier: 'values'
print callback(1, 2, 3) # this line also shouldn't change, if possible.
Run
The alternative is to mark your entire template as `{.dirty.}`, but that would
make `localFunc` also visible and would cause an error if you ever called your
template twice (because now you would redefine `localFunc`).
Of course you can also drop the `proc localFunc` part entirely and just do this
(modified slightly so I could run it in the playground without errors):
var callback: proc(args: varargs[int]): string # this line shouldn't change
template runWithBody(minLength: int, body: untyped) =
callback = proc(values {.inject.}: varargs[int]): string =
if values.len >= minLength:
body
else:
raise newException(Exception, "Called function contains less than " &
$minLength & " arguments")
runWithBody(2):
result = $(values[0] + values[1]) # here is the problem: Error:
undeclared identifier: 'values'
echo callback(1, 2, 3) # this line also shouldn't change, if possible.
Run