Class: Stupidedi::Zipper::StackCursor

Inherits:
AbstractCursor show all
Defined in:
lib/stupidedi/zipper/stack_cursor.rb

Instance Attribute Summary collapse

Querying the Tree Location collapse

Traversing the Tree collapse

Editing the Tree collapse

Instance Method Summary collapse

Methods inherited from AbstractCursor

#child, #children, #depth, #descendant, #first?, #flatten, #insert_left, #insert_right, #last?, #root

Constructor Details

#initialize(node, path, parent) ⇒ StackCursor

Returns a new instance of StackCursor.



20
21
22
23
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 20

def initialize(node, path, parent)
  @node, @path, @parent =
    node, path, parent
end

Instance Attribute Details

#node#leaf?, ... (readonly)

Returns:



11
12
13
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 11

def node
  @node
end

#parentAbstractCursor (readonly)

Returns:



18
19
20
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 18

def parent
  @parent
end

#pathHole (readonly)

Returns:



14
15
16
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 14

def path
  @path
end

Instance Method Details

#append(node) ⇒ EditedCursor, void

Insert a new sibling node after (to the right of) the current node, and navigate to the new sibling node

Returns:



109
110
111
112
113
114
115
116
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 109

def append(node)
  if root?
    raise Exceptions::ZipperError,
      "root node has no siblings"
  end

  replace(node)
end

#append_child(child) ⇒ Object



133
134
135
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 133

def append_child(child)
  StackCursor.new(child, Hole.new([], @path, []), self)
end

#between(other) ⇒ Object



45
46
47
48
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 45

def between(other)
  raise Exceptions::ZipperError,
    "stack cursor doesn't support this method"
end

#copy(changes = {}) ⇒ Object



25
26
27
28
29
30
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 25

def copy(changes = {})
  StackCursor.new \
    changes.fetch(:node, @node),
    changes.fetch(:path, @path),
    changes.fetch(:parent, @parent)
end

#dangleObject



154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 154

def dangle
  if leaf?
    StackCursor.new(nil, Hole.new([], @path, []), self)
  else
    head, *tail = @node.children

    unless tail.empty?
      raise Exceptions::ZipperError,
        "stack cursor doesn't support nodes with multiple children"
    end

    StackCursor.new(head, Hole.new([], @path, []), self)
  end
end

#deleteEditedCursor, void

Remove the current node, and navigate to the next (rightward) node if one exists. Otherwise, navigate to the previous (leftward) node if one exists. Otherwise, create a placeholder where the next sibling node will be created.

Returns:



145
146
147
148
149
150
151
152
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 145

def delete
  if root?
    raise Exceptions::ZipperError,
      "cannot delete root node"
  end

  @parent
end

#downMemoizedCursor

Navigate to the first child node

Returns:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 88

def down
  if leaf?
    raise Exceptions::ZipperError,
      "cannot descend into leaf node"
  end

  head, *tail = @node.children

  unless tail.empty?
    raise Exceptions::ZipperError,
      "stack cursor doesn't support nodes with multiple children"
  end

  StackCursor.new(head, Hole.new([], @path, []), self)
end

#firstAbstractCursor

Navigate to the first (leftmost) sibling node

Returns:



54
55
56
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 54

def first
  self
end

#lastAbstractCursor

Navigate to the last (rightmost) sibling node

Returns:



59
60
61
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 59

def last
  self
end

#leaf?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 36

def leaf?
  @node.leaf? or @node.children.empty?
end

#nextAbstractCursor, void

Navigate to the next (rightward) sibling node

Returns:



65
66
67
68
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 65

def next
  raise Exceptions::ZipperError,
    "stack cursor doesn't maintain siblings"
end

#prepend(node) ⇒ EditedCursor, void

Insert a new sibling node before (to the left of) the current node, and navigate to the new sibling node

Returns:



120
121
122
123
124
125
126
127
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 120

def prepend(node)
  if root?
    raise Exceptions::ZipperError,
      "root node has no siblings"
  end

  replace(node)
end

#prepend_child(child) ⇒ Object



129
130
131
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 129

def prepend_child(child)
  StackCursor.new(child, Hole.new([], @path, []), self)
end

#prevAbstractCursor, void

Navigate to the previous (leftward) sibling node

Returns:



72
73
74
75
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 72

def prev
  raise Exceptions::ZipperError,
    "stack cursor doesn't maintain siblings"
end

#replace(node) ⇒ AbstractCursor, RootCursor

Replace the current node with the given node

Returns:



139
140
141
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 139

def replace(node)
  StackCursor.new(node, @path, @parent)
end

#root?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 41

def root?
  @path.root?
end

#upAbstractCursor

Navigate to the parent node

Returns:



78
79
80
81
82
83
84
85
# File 'lib/stupidedi/zipper/stack_cursor.rb', line 78

def up
  if root?
    raise Exceptions::ZipperError,
      "root node has no siblings"
  end

  @parent
end