Class: Linked::List
- Inherits:
-
Object
- Object
- Linked::List
- Includes:
- ListEnumerable
- Defined in:
- lib/linked/list.rb
Overview
This class provides a way extend the regular chain of listable items with the concept of an empty chain.
Lists are ment to behave more like arrays, and respond to many of the same methods.
Instance Method Summary collapse
-
#==(other) ⇒ true, false
(also: #eql?)
Two lists are considered equal if the n:th item from each list are equal.
- #empty? ⇒ true, false
-
#freeze ⇒ self
Calls #freeze on all items in the list, as well as the head and the tail (eol).
-
#include?(item) ⇒ true, false
Check if an item is in the list.
-
#initialize ⇒ List
constructor
Initializes the list.
-
#initialize_dup(source) ⇒ Object
When copying a list its entire item chain needs to be copied as well.
-
#inspect_list(&block) ⇒ Object
(also: #inspect)
Overrides the default inspect method to provide a more useful view of the list.
-
#item ⇒ Listable
Access the first item in the list.
-
#pop ⇒ Listable?
Pop the last item off the list.
-
#push(object) ⇒ self
(also: #<<)
Insert an item at the end of the list.
-
#shift ⇒ Listable?
Shift the first item off the list.
-
#unshift(object) ⇒ self
Insert an item at the beginning of the list.
Methods included from ListEnumerable
#count, #each_item, #first, #last, #reverse_each_item
Constructor Details
#initialize ⇒ List
Initializes the list.
14 15 16 17 |
# File 'lib/linked/list.rb', line 14 def initialize reset_list super end |
Instance Method Details
#==(other) ⇒ true, false Also known as: eql?
Two lists are considered equal if the n:th item from each list are equal.
47 48 49 50 51 52 53 |
# File 'lib/linked/list.rb', line 47 def ==(other) return false unless other.is_a? self.class return false unless other.count == count other_items = other.each_item each_item.all? { |item| item == other_items.next } end |
#empty? ⇒ true, false
59 60 61 |
# File 'lib/linked/list.rb', line 59 def empty? nil.eql? @_chain end |
#freeze ⇒ self
Calls #freeze on all items in the list, as well as the head and the tail (eol).
141 142 143 144 |
# File 'lib/linked/list.rb', line 141 def freeze each_item(&:freeze) super end |
#include?(item) ⇒ true, false
Check if an item is in the list.
131 132 133 134 135 |
# File 'lib/linked/list.rb', line 131 def include?(item) return false if empty? # TODO: This works fine, but looks wrong. @_chain.in_chain? item end |
#initialize_dup(source) ⇒ Object
When copying a list its entire item chain needs to be copied as well. Therefore #dup will be called on each of the original lists items, making this operation quite expensive.
24 25 26 27 28 29 |
# File 'lib/linked/list.rb', line 24 def initialize_dup(source) reset_list source.each_item { |item| push item.dup } super end |
#inspect_list(&block) ⇒ Object Also known as: inspect
Overrides the default inspect method to provide a more useful view of the list.
Importantly this implementation supports nested lists and will return a tree like structure.
152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/linked/list.rb', line 152 def inspect_list(&block) res = [block_given? ? yield(self) : object_identifier] each_item do |item| lines = item.inspect(&block).split "\n" res.push((item.last? ? '└─╴' : '├─╴') + lines.shift) padding = item.last? ? ' ' : '│ ' lines.each { |line| res.push padding + line } end res.join("\n") end |
#item ⇒ Listable
Access the first item in the list. If the list is empty a NoMethodError will be raised. This mirrors the behaviour of Item#item and allows other methods that work on List objects to easily and interchangeably accept both lists and items as arguments.
37 38 39 40 |
# File 'lib/linked/list.rb', line 37 def item raise NoMethodError if empty? @_chain end |
#pop ⇒ Listable?
Pop the last item off the list.
89 90 91 92 93 |
# File 'lib/linked/list.rb', line 89 def pop return nil if empty? list_tail.first? ? last.tap { @_chain = nil } : list_tail.delete end |
#push(object) ⇒ self Also known as: <<
Insert an item at the end of the list. If the given object is not an object responding to #item it will be treated as a value. The value will be wraped in a new Item create by #create_item.
See Item#append for more details.
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/linked/list.rb', line 71 def push(object) item = coerce_item object if empty? @_chain = item else list_tail.append item end self end |
#shift ⇒ Listable?
Shift the first item off the list.
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/linked/list.rb', line 114 def shift return nil if empty? if list_head.last? @_chain.tap { @_chain = nil } else old_head = list_head @_chain = list_head.next old_head.delete end end |
#unshift(object) ⇒ self
Insert an item at the beginning of the list. If the given object is not an object responding to #item it will be treated as a value. The value will be wraped in a new Item create by #create_item.
See Item#prepend for more details.
103 104 105 106 107 108 |
# File 'lib/linked/list.rb', line 103 def unshift(object) item = coerce_item object @_chain = empty? ? item.chain : @_chain.prepend(item) self end |