letUtils

  Source

A collection of small templates and macros that aid in limiting the scope of mutable variables as much as practical.

Macros

macro freezeVars(body: untyped): untyped

Create a let binding for each top-level var in body; make other declarations inaccessible from outside.

Example:

freezeVars:
  var fib = @[0, 1]
  for i in 2 ..< 13:
    fib &= fib[^1] + fib[^2]
# From now on, you cannot modify `fib`.
echo fib
assert not compiles (fib[0] = 123)

Example:

proc process(id: int): bool =
  freezeVars:
    var thing = findById id
    if thing == nil:
      if id < 0:
        return false
      thing = insert id
  
  validate thing
  Source

Templates

template asLet(val, body: untyped): untyped
Equivalent to:
let tmp = val
with tmp:
  body
tmp

Example:

processObj:
  getObj().asLet:
    field = 1

Since: Nim 1.2.

See also:

  Source
template asLet(val, name, body: untyped): untyped
Equivalent to:
let name = val
body
name

Example:

processObj:
  getObj().asLet obj:
    obj.field = 1
  Source
template asVar(val, body: untyped): untyped
Equivalent to:
var tmp = val
with tmp:
  body
tmp

Example:

from std/strbasics import strip

assert " test\n".asVar(strip) == "test"

Since: Nim 1.2.

See also:

  Source
template asVar(val, name, body: untyped): untyped
Equivalent to:
var name = val
body
name

Example:

from std/strbasics import strip

processStr:
  getStr().asVar s:
    s.strip
  Source
template scope(body: untyped): untyped

Open a new lexical scope (variables declared in the body are not accessible outside). Similar to the built-in block language construct but does not interfere with break. All credits for the implementation go to @markspanbroek.

Unlabeled break inside a block has been deprecated in Nim 2.0; see details and rationale.

  Source
template viaVar[T](t: type[T]; body: untyped): T
Equivalent to:
var tmp: T
with tmp:
  body
tmp

Example:

run:
  Config.viaVar:
    logFile = "prog.log"
    verbosity = 1
    merge loadFromFile "config.kdl"

Since: Nim 1.2.

See also:

  Source
template viaVar[T](t: type[T]; name, body: untyped): T
Equivalent to:
var name: T
body
name

Example:

processSeq:
  seq[string].viaVar data:
    for i in 0 ..< 5:
      data &= $i

See also:

  Source