Class: Async::List
- Inherits:
-
Object
- Object
- Async::List
- Defined in:
- lib/async/list.rb
Overview
Direct Known Subclasses
Defined Under Namespace
Classes: Node
Instance Attribute Summary collapse
-
#head ⇒ Object
Points at the end of the list.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
-
#tail ⇒ Object
Points at the start of the list.
Instance Method Summary collapse
-
#added(node) ⇒ Object
A callback that is invoked when an item is added to the list.
-
#append(node) ⇒ Object
Append a node to the end of the list.
-
#each ⇒ Object
Iterate over each node in the linked list.
- #empty? ⇒ Boolean
- #first ⇒ Object
-
#include?(needle) ⇒ Boolean
Determine whether the given node is included in the list.
-
#initialize ⇒ List
constructor
Initialize a new, empty, list.
- #last ⇒ Object
- #prepend(node) ⇒ Object
-
#remove(node) ⇒ Object
Remove the node.
-
#remove?(node) ⇒ Boolean
Remove the node if it is in a list.
-
#removed(node) ⇒ Object
A callback that is invoked when an item is removed from the list.
-
#stack(node, &block) ⇒ Object
Add the node, yield, and the remove the node.
-
#to_s ⇒ Object
(also: #inspect)
Print a short summary of the list.
Constructor Details
#initialize ⇒ List
Initialize a new, empty, list.
10 11 12 13 14 |
# File 'lib/async/list.rb', line 10 def initialize @head = self @tail = self @size = 0 end |
Instance Attribute Details
#head ⇒ Object
Points at the end of the list.
24 25 26 |
# File 'lib/async/list.rb', line 24 def head @head end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
29 30 31 |
# File 'lib/async/list.rb', line 29 def size @size end |
#tail ⇒ Object
Points at the start of the list.
27 28 29 |
# File 'lib/async/list.rb', line 27 def tail @tail end |
Instance Method Details
#added(node) ⇒ Object
A callback that is invoked when an item is added to the list.
32 33 34 35 |
# File 'lib/async/list.rb', line 32 def added(node) @size += 1 return node end |
#append(node) ⇒ Object
Append a node to the end of the list.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/async/list.rb', line 38 def append(node) if node.head raise ArgumentError, "Node is already in a list!" end node.tail = self @head.tail = node node.head = @head @head = node return added(node) end |
#each ⇒ Object
Iterate over each node in the linked list. It is generally safe to remove the current node, any previous node or any future node during iteration.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/async/list.rb', line 128 def each return to_enum unless block_given? current = self while true node = current.tail # binding.irb if node.nil? && !node.equal?(self) break if node.equal?(self) yield node # If the node has deleted itself or any subsequent node, it will no longer be the next node, so don't use it for continued traversal: if current.tail.equal?(node) current = node end end return self end |
#empty? ⇒ Boolean
120 121 122 |
# File 'lib/async/list.rb', line 120 def empty? @tail.equal?(self) end |
#first ⇒ Object
162 163 164 165 166 |
# File 'lib/async/list.rb', line 162 def first unless @tail.equal?(self) @tail end end |
#include?(needle) ⇒ Boolean
Determine whether the given node is included in the list.
153 154 155 156 157 158 159 |
# File 'lib/async/list.rb', line 153 def include?(needle) self.each do |item| return true if needle.equal?(item) end return false end |
#last ⇒ Object
169 170 171 172 173 |
# File 'lib/async/list.rb', line 169 def last unless @head.equal?(self) @head end end |
#prepend(node) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/async/list.rb', line 51 def prepend(node) if node.head raise ArgumentError, "Node is already in a list!" end node.head = self @tail.head = node node.tail = @tail @tail = node return added(node) end |
#remove(node) ⇒ Object
Remove the node. If it was already removed, this will raise an error.
You should be careful to only remove nodes that are part of this list.
99 100 101 102 103 104 105 106 |
# File 'lib/async/list.rb', line 99 def remove(node) # One downside of this interface is we don't actually check if the node is part of the list defined by `self`. This means that there is a potential for a node to be removed from a different list using this method, which in can throw off book-keeping when lists track size, etc. unless node.head raise ArgumentError, "Node is not in a list!" end remove!(node) end |
#remove?(node) ⇒ Boolean
Remove the node if it is in a list.
You should be careful to only remove nodes that are part of this list.
85 86 87 88 89 90 91 |
# File 'lib/async/list.rb', line 85 def remove?(node) if node.head return remove!(node) end return nil end |
#removed(node) ⇒ Object
A callback that is invoked when an item is removed from the list.
75 76 77 78 |
# File 'lib/async/list.rb', line 75 def removed(node) @size -= 1 return node end |
#stack(node, &block) ⇒ Object
Add the node, yield, and the remove the node.
67 68 69 70 71 72 |
# File 'lib/async/list.rb', line 67 def stack(node, &block) append(node) return yield(node) ensure remove!(node) end |
#to_s ⇒ Object Also known as: inspect
Print a short summary of the list.
17 18 19 |
# File 'lib/async/list.rb', line 17 def to_s "#<#{self.class.name} size=#{@size}>" end |