Skip to content

Instantly share code, notes, and snippets.

@cryzed

cryzed/test2.nim Secret

Created December 7, 2015 16:53
Show Gist options
  • Save cryzed/5acdc21d1560b8a99d62 to your computer and use it in GitHub Desktop.
Save cryzed/5acdc21d1560b8a99d62 to your computer and use it in GitHub Desktop.
import strutils
type
NodeKind = enum
NodeKind1, NodeKind2, NodeKind3
# Only some Nodes should have children. You can't name two attributes within a
# type definition using a case statement the same as of yet (probably a bug).
# You will get a redefinition error for the attribute, even though both
# branches are never active at the same time.
Node = ref object
value: string
case kind: NodeKind
of NodeKind1:
internalChildren: seq[Node]
of NodeKind2:
internalChildren2: seq[Node]
of NodeKind3:
something: string
# So we write a custom accessor to transparently grab the correct children
# attribute for the Node
proc children(node: Node): var seq[Node] =
case node.kind:
of NodeKind1:
return node.internalChildren
of NodeKind2:
return node.internalChildren2
else:
raise newException(ValueError, "$1 can't have children".format(node.kind))
proc main() =
var node = Node(kind: NodeKind1, value: "Hello World", internalChildren: @[])
let childNode = Node(kind: NodeKind1, value: "Child 1", internalChildren: @[])
node.internalChildren.add childNode
# Works exactly as expected! But we have to use internalChildren and
# internalChildren2 depending on type. Now let's attempt to use our accessor
# proc to hide that complexity from us
echo node.repr
# This calls the children proc and returns the children field of the given
# nide.
var referenceToChildren = node.children
let childNode2 = Node(kind: NodeKind1, value: "Child 2", internalChildren: @[])
referenceToChildren.add childNode2
# Child 2 doesn't appear in the object structure, apparently node.children
# returned a copy of the seq[Node]-children data structure and modified it
# instead of the original object
echo node.repr
# Output:
discard """
ref 00328028 --> [value = 00329028"Hello World",
NodeKind1internalChildren = 00329048[ref 00328040 --> [value = 00328058"Child 1",
NodeKind1internalChildren = 0032a038[]]]]
ref 00328028 --> [value = 00329028"Hello World",
NodeKind1internalChildren = 00329048[ref 00328040 --> [value = 00328058"Child 1",
NodeKind1internalChildren = 0032a038[]]]]
"""
when isMainModule:
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment