diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2020-11-16 23:40:17 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-17 08:40:17 +0100 |
commit | 50d035b7896b85184fc6e97e22f32a189d76b81b (patch) | |
tree | bd6e2eb89f809bd8270c25e39b39672519b4a5a9 | |
parent | 61352d5a203e76e3334b21766bdbd4ebc71c300a (diff) | |
download | Nim-50d035b7896b85184fc6e97e22f32a189d76b81b.tar.gz |
defer: improve manual, clarify difference wrt try/finally (#16010)
-rw-r--r-- | doc/manual.rst | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/doc/manual.rst b/doc/manual.rst index 9a4ae378d..1a23c5997 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -4414,7 +4414,9 @@ Custom exceptions can be raised like any others, e.g.: Defer statement --------------- -Instead of a ``try finally`` statement a ``defer`` statement can be used. +Instead of a ``try finally`` statement a ``defer`` statement can be used, which +avoids lexical nesting and offers more flexibility in terms of scoping as shown +below. Any statements following the ``defer`` in the current block will be considered to be in an implicit try block: @@ -4423,7 +4425,7 @@ to be in an implicit try block: :test: "nim c $1" proc main = - var f = open("numbers.txt") + var f = open("numbers.txt", fmWrite) defer: close(f) f.write "abc" f.write "def" @@ -4441,6 +4443,33 @@ Is rewritten to: finally: close(f) +When `defer` is at the outermost scope of a template/macro, its scope extends +to the block where the template is called from: + +.. code-block:: nim + :test: "nim c $1" + + template safeOpenDefer(f, path) = + var f = open(path, fmWrite) + defer: close(f) + + template safeOpenFinally(f, path, body) = + var f = open(path, fmWrite) + try: body # without `defer`, `body` must be specified as parameter + finally: close(f) + + block: + safeOpenDefer(f, "/tmp/z01.txt") + f.write "abc" + block: + safeOpenFinally(f, "/tmp/z01.txt"): + f.write "abc" # adds a lexical scope + block: + var f = open("/tmp/z01.txt", fmWrite) + try: + f.write "abc" # adds a lexical scope + finally: close(f) + Top-level ``defer`` statements are not supported since it's unclear what such a statement should refer to. |