summary refs log tree commit diff stats
path: root/doc/manual.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual.rst')
-rw-r--r--doc/manual.rst33
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.