lib/linked/list.rb in linked-0.2.1 vs lib/linked/list.rb in linked-0.3.0

- old
+ new

@@ -60,28 +60,28 @@ source.each_item { |item| push item.dup } super end - + # Identity method that simply return the list. This method mirrors Item#list # and allows other methods that work on List objects to easily and # interchangebly accept both lists and items as arguments. # # Returns the list itself. - + def list self end - + # 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. # # Returns the first item in the list. - + def item raise NoMethodError if empty? eol.next end @@ -165,22 +165,22 @@ def empty? @item_count == 0 end - # Insert an item at the end of the list. If the given object is not an Item, - # or a decendant of Item, it will be treated as a value. Depending on the - # state of the list the value will be - # a) wraped in a new instance of Item if the list is empty or - # b) wraped in an object of the same class as the last item in the list. + # 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. # - # item - the item to insert, or an arbitrary value. + # See Item#append for more details. # + # object - the item to insert, or an arbitrary object. + # # Returns self. - def push(item) - eol.append item + def push(object) + eol.append object self end alias << push @@ -192,21 +192,21 @@ return nil if empty? last.delete end # Insert an item at the beginning of the list. If the given object is not an - # Item, or a decendant of Item, it will be treated as a value. Depending on - # the state of the list the value will be - # a) wraped in a new instance of Item if the list is empty or - # b) wraped in an object of the same class as the last item in the list. + # object responding to #item it will be treated as a value. The value will + # be wraped in a new Item create by #create_item. # - # item - the item to insert, or an arbitrary value. + # See Item#prepend for more details. # + # object - the item to insert, or an arbitrary object. + # # Returns self. - def unshift(item) - eol.prepend item + def unshift(object) + eol.prepend object self end # Shift the first item off the list. # @@ -214,36 +214,28 @@ def shift return nil if empty? first.delete end - + # Check if an item is in the list. # # item - Item, or any object that may be in the list. # # Returns true if the given item is in the list, otherwise false. - + def include?(item) item.in? self rescue NoMethodError false end - # Iterates over each item in the list, either in normal or reverse order. If - # a block is not given an enumerator is returned. - # - # reverse - flips the iteration order if true. Note that this option is - # depricated and will be removed in the next major release. + # Iterates over each item in the list If a block is not given an enumerator + # is returned. - def each_item(reverse: false, &block) - if reverse - warn '[DEPRECATION] the option `reverse: true` will be removed in a future release. Please call `reverse_each_item` instead.' - eol.before(&block) - else - eol.after(&block) - end + def each_item(&block) + eol.after(&block) end alias each each_item # Iterates over each item in the list in reverse order. If a block is not @@ -283,10 +275,24 @@ end res.join("\n") end + # Protected factory method for creating items compatible with the list. This + # method is called whenever an arbitrary object is pushed or unshifted onto + # the list and need to be wraped inside an Item. + # + # This method can be overridden to suport different Item types. + # + # args - any arguments will be passed on to Item.new. + # + # Returns a new Item. + + protected def create_item(*args) + Item.new(*args) + end + # Internal method to grow the list with n elements. Never call this method # without also inserting the n elements. # # n - the number of items that has been/will be added to the list. # @@ -304,21 +310,21 @@ # Returns updated the item count. private def shrink(n = 1) @item_count -= n end - + # Private method to clear the list. Never call this method without also # modifying the items in the list, as this operation leavs them in an # inconsistant state. If the list items are kept, make sure to # a) clear the `prev` pointer of the first item and # b) clear the `next` pointer of the last item. - + private def clear head.send :next=, tail tail.send :prev=, head - + @item_count = 0 end # Protected helper method that returns the first n items, starting just # after item, given that there are items_left items left. Knowing the exact @@ -340,11 +346,11 @@ protected def first_item_after(item, n, items_left = @item_count) # Optimize for these cases return nil if n == 0 return n > 1 ? [] : nil if item.next!.nil? return item.next if n == 1 - + n = items_left if n > items_left arr = Array.new n n.times { |i| arr[i] = item = item.next } arr @@ -374,21 +380,21 @@ return nil if n == 0 return n > 1 ? [] : nil if item.prev!.nil? return item.prev if n == 1 n = items_left if n > items_left - + arr = Array.new n (n - 1).downto(0) { |i| arr[i] = item = item.prev } arr rescue StopIteration arr.compact! || arr end - + # This method is called whenever the module is included somewhere. In the # special case when List is included in an Item the #item method must be # changed to return self. - + def self.included(klass) klass.send(:define_method, :item) { self } if klass < Item end end end