-
-
Save cryzed/5acdc21d1560b8a99d62 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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