with.nim 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2020 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module implements the `with` macro for easy
  10. ## function chaining. See https://github.com/nim-lang/RFCs/issues/193
  11. ## and https://github.com/nim-lang/RFCs/issues/192 for details leading to this
  12. ## particular design.
  13. ##
  14. ## **Since:** version 1.2.
  15. import std/[macros, private / underscored_calls]
  16. macro with*(arg: typed; calls: varargs[untyped]): untyped =
  17. ## This macro provides `chaining`:idx: of function calls.
  18. ## It does so by patching every call in `calls` to
  19. ## use `arg` as the first argument.
  20. ##
  21. ## .. caution:: This evaluates `arg` multiple times!
  22. runnableExamples:
  23. var x = "yay"
  24. with x:
  25. add "abc"
  26. add "efg"
  27. doAssert x == "yayabcefg"
  28. var a = 44
  29. with a:
  30. += 4
  31. -= 5
  32. doAssert a == 43
  33. # Nesting works for object types too!
  34. var foo = (bar: 1, qux: (baz: 2))
  35. with foo:
  36. bar = 2
  37. with qux:
  38. baz = 3
  39. doAssert foo.bar == 2
  40. doAssert foo.qux.baz == 3
  41. result = newNimNode(nnkStmtList, arg)
  42. underscoredCalls(result, calls, arg)