summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2020-01-18 04:33:30 -0800
committerAndreas Rumpf <rumpf_a@web.de>2020-01-18 13:33:30 +0100
commitbc14453f69b9bde449cb52655eb6ffe571d6a28b (patch)
tree144b56c362ed26489ed33dcaab827569da1b84c8 /lib/system
parentf6ba4e81b057063938f7c3910b222149f306de85 (diff)
downloadNim-bc14453f69b9bde449cb52655eb6ffe571d6a28b.tar.gz
fix docs + API for fieldPairs, fields (#13189)
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/iterators.nim66
1 files changed, 40 insertions, 26 deletions
diff --git a/lib/system/iterators.nim b/lib/system/iterators.nim
index 549aa5886..53b287db0 100644
--- a/lib/system/iterators.nim
+++ b/lib/system/iterators.nim
@@ -217,45 +217,38 @@ iterator mitems*(a: var string): var char {.inline.} =
 
 
 iterator fields*[T: tuple|object](x: T): RootObj {.
-  magic: "Fields", noSideEffect.}
+  magic: "Fields", noSideEffect.} =
   ## Iterates over every field of `x`.
   ##
   ## **Warning**: This really transforms the 'for' and unrolls the loop.
   ## The current implementation also has a bug
   ## that affects symbol binding in the loop body.
-iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[a, b: RootObj] {.
-  magic: "Fields", noSideEffect.}
+  runnableExamples:
+    var t = (1, "foo")
+    for v in fields(t): v = default(type(v))
+    doAssert t == (0, "")
+
+iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[key: string, val: RootObj] {.
+  magic: "Fields", noSideEffect.} =
   ## Iterates over every field of `x` and `y`.
   ##
   ## **Warning**: This really transforms the 'for' and unrolls the loop.
   ## The current implementation also has a bug that affects symbol binding
   ## in the loop body.
-iterator fieldPairs*[T: tuple|object](x: T): RootObj {.
-  magic: "FieldPairs", noSideEffect.}
+  runnableExamples:
+    var t1 = (1, "foo")
+    var t2 = default(type(t1))
+    for v1, v2 in fields(t1, t2): v2 = v1
+    doAssert t1 == t2
+
+iterator fieldPairs*[T: tuple|object](x: T): tuple[key: string, val: RootObj] {.
+  magic: "FieldPairs", noSideEffect.} =
   ## Iterates over every field of `x` returning their name and value.
   ##
   ## When you iterate over objects with different field types you have to use
   ## the compile time ``when`` instead of a runtime ``if`` to select the code
   ## you want to run for each type. To perform the comparison use the `is
-  ## operator <manual.html#generics-is-operator>`_. Example:
-  ##
-  ## .. code-block:: Nim
-  ##   type
-  ##     Custom = object
-  ##       foo: string
-  ##       bar: bool
-  ##
-  ##   proc `$`(x: Custom): string =
-  ##     result = "Custom:"
-  ##     for name, value in x.fieldPairs:
-  ##       when value is bool:
-  ##         result.add("\n\t" & name & " is " & $value)
-  ##       else:
-  ##         if value.isNil:
-  ##           result.add("\n\t" & name & " (nil)")
-  ##         else:
-  ##           result.add("\n\t" & name & " '" & value & "'")
-  ##
+  ## operator <manual.html#generics-is-operator>`_.
   ## Another way to do the same without ``when`` is to leave the task of
   ## picking the appropriate code to a secondary proc which you overload for
   ## each field type and pass the `value` to.
@@ -263,12 +256,33 @@ iterator fieldPairs*[T: tuple|object](x: T): RootObj {.
   ## **Warning**: This really transforms the 'for' and unrolls the loop. The
   ## current implementation also has a bug that affects symbol binding in the
   ## loop body.
+  runnableExamples:
+    type
+      Custom = object
+        foo: string
+        bar: bool
+    proc `$`(x: Custom): string =
+      result = "Custom:"
+      for name, value in x.fieldPairs:
+        when value is bool:
+          result.add("\n\t" & name & " is " & $value)
+        else:
+          result.add("\n\t" & name & " '" & value & "'")
 
 iterator fieldPairs*[S: tuple|object, T: tuple|object](x: S, y: T): tuple[
-  a, b: RootObj] {.
-  magic: "FieldPairs", noSideEffect.}
+  key: string, a, b: RootObj] {.
+  magic: "FieldPairs", noSideEffect.} =
   ## Iterates over every field of `x` and `y`.
   ##
   ## **Warning**: This really transforms the 'for' and unrolls the loop.
   ## The current implementation also has a bug that affects symbol binding
   ## in the loop body.
+  runnableExamples:
+    type Foo = object
+      x1: int
+      x2: string
+    var a1 = Foo(x1: 12, x2: "abc")
+    var a2: Foo
+    for name, v1, v2 in fieldPairs(a1, a2):
+      when name == "x2": v2 = v1
+    doAssert a2 == Foo(x1: 0, x2: "abc")