class Fzip::Zipper
Attributes
adapter[R]
at_end[R]
lefts[R]
node[R]
parent[R]
path[R]
rights[R]
Public Class Methods
new(adapter, node, lefts = nil, path = nil, parent = nil, rights = nil, changed = false, at_end = false)
click to toggle source
# File lib/fzip/zipper.rb, line 11 def initialize(adapter, node, lefts = nil, path = nil, parent = nil, rights = nil, changed = false, at_end = false) @adapter = adapter @node = node @lefts = lefts @rights = rights @path = path # Array[Node] @parent = parent # Zipper @changed = changed @at_end = at_end end
Public Instance Methods
append_child(item)
click to toggle source
# File lib/fzip/zipper.rb, line 158 def append_child(item) replace(make_node(node, children + [item])) end
branch?()
click to toggle source
# File lib/fzip/zipper.rb, line 37 def branch? adapter.branch?(node) end
changed?()
click to toggle source
# File lib/fzip/zipper.rb, line 50 def changed? @changed end
children()
click to toggle source
# File lib/fzip/zipper.rb, line 41 def children raise "called children on a leaf node" unless branch? @cs ||= adapter.children(node) end
down()
click to toggle source
# File lib/fzip/zipper.rb, line 58 def down if branch? && children.any? new( node: children.first, lefts: [], path: path ? [node] + path : [node], parent: self, rights: children.drop(1) ) end end
each() { |loc| ... }
click to toggle source
# File lib/fzip/zipper.rb, line 210 def each return to_enum unless block_given? loc = self until (loc = loc.next).end? yield loc end end
edit() { |node)| ... }
click to toggle source
# File lib/fzip/zipper.rb, line 150 def edit replace(yield node) end
end?()
click to toggle source
# File lib/fzip/zipper.rb, line 54 def end? @at_end end
insert_child(item)
click to toggle source
# File lib/fzip/zipper.rb, line 154 def insert_child(item) replace(make_node(node, [item] + children)) end
insert_left(item)
click to toggle source
# File lib/fzip/zipper.rb, line 127 def insert_left(item) raise "insert at top" unless path new( lefts: lefts + [item], changed: true ) end
insert_right(item)
click to toggle source
# File lib/fzip/zipper.rb, line 135 def insert_right(item) raise "insert at top" unless path new( rights: [item] + rights, changed: true ) end
left()
click to toggle source
# File lib/fzip/zipper.rb, line 108 def left if path && lefts && !lefts.empty? new( node: lefts.last, lefts: lefts[0...-1], rights: [node] + rights ) end end
leftmost()
click to toggle source
# File lib/fzip/zipper.rb, line 118 def leftmost return self unless path && lefts && !lefts.empty? new( node: lefts.first, lefts: [], rights: (lefts + [node] + rights).drop(1) ) end
make_node(node, children)
click to toggle source
# File lib/fzip/zipper.rb, line 46 def make_node(node, children) adapter.make_node(node, children) end
new(changes = {})
click to toggle source
# File lib/fzip/zipper.rb, line 24 def new(changes = {}) self.class.new( @adapter, changes.fetch(:node) { self.node }, changes.fetch(:lefts) { self.lefts }, changes.fetch(:path) { self.path }, changes.fetch(:parent) { self.parent }, changes.fetch(:rights) { self.rights }, changes.fetch(:changed) { self.changed? }, changes.fetch(:end) { self.end? } ) end
next()
click to toggle source
# File lib/fzip/zipper.rb, line 162 def next backtrack = ->(node) { if node.up node.up.right || backtrack.(node.up) else node.new(end: true) end } (self if end?) || (branch? && down) || right || backtrack.(self) end
prev()
click to toggle source
# File lib/fzip/zipper.rb, line 177 def prev return up unless loc = left loop do if child = loc.branch? && loc.down loc = child.rightmost else return loc end end end
remove()
click to toggle source
Removes the node at loc, returning the loc that would have preceded it in a depth-first walk.
# File lib/fzip/zipper.rb, line 190 def remove raise "Remove at top" unless path if lefts.empty? parent.new( node: make_node(parent.node, rights), changed: true ) else loc = new( node: lefts.first, lefts: lefts.drop(1), changed: true ) loop do return loc unless child = loc.branch? && loc.down loc = child.rightmost end end end
replace(item)
click to toggle source
# File lib/fzip/zipper.rb, line 143 def replace(item) new( node: item, changed: true ) end
right()
click to toggle source
# File lib/fzip/zipper.rb, line 89 def right if path && rights && !rights.empty? new( node: rights.first, lefts: lefts + [node], rights: rights.drop(1) ) end end
rightmost()
click to toggle source
# File lib/fzip/zipper.rb, line 99 def rightmost return self unless path && rights && !rights.empty? new( node: rights.last, lefts: (lefts + [node] + rights)[0..-2], rights: [] ) end
root()
click to toggle source
# File lib/fzip/zipper.rb, line 84 def root return node unless path up.root end
up()
click to toggle source
# File lib/fzip/zipper.rb, line 70 def up if path return parent unless changed? parent_path = path.drop(1) new( node: make_node(parent.node, lefts + [node] + rights), lefts: parent.lefts, path: parent_path.empty? ? nil : parent_path, parent: parent.parent, rights: parent.rights ) end end