linked 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 513dbae22fea14a370f2181ef4da797264121631
4
- data.tar.gz: 685eb16cb3380aec648af578118b54416af20772
3
+ metadata.gz: ea4e0ba7b896f4e64d885d73066e65e4e08b49ea
4
+ data.tar.gz: 7913edd077d33d5a7b36982568d5b3cb46cc7c1e
5
5
  SHA512:
6
- metadata.gz: b3cfa2318674d45841c7a075250cb88d1095a5df6c56a270eda3bf60bce06cd41db8612f1d1df520cd9ab32ded2f73aedb36f71e1fb410c7d875e77f4d128e62
7
- data.tar.gz: 6557225296323c2ff767766bde4ea13067e39103bc84a9e3fb43229991ca65156373475ad7091412174608c11c4b7bdf889274d96d975e9fee3bd493a1f8aab0
6
+ metadata.gz: 1467066f7e5af4ddc7eca82013d94777b956d7c93497502977fd776523e570bb7ae0d441940cb9a275f567c48750a50cff80881de98e1ca89c1592b7a5aff599
7
+ data.tar.gz: fac1a3393906af1c00f788fbc4e5eb30ab2b48e042190f898b43944a6ae4718baec62b9c0e0193537cc4f484f4a518f435abf0a7611bb5f28215d6aa8128b54f
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Linked
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/linked.svg)](https://badge.fury.io/rb/linked)
3
4
  [![Build Status](https://travis-ci.org/seblindberg/ruby-linked.svg?branch=master)](https://travis-ci.org/seblindberg/ruby-linked)
4
5
  [![Coverage Status](https://coveralls.io/repos/github/seblindberg/ruby-linked/badge.svg?branch=master)](https://coveralls.io/github/seblindberg/ruby-linked?branch=master)
5
6
  [![Inline docs](http://inch-ci.org/github/seblindberg/ruby-linked.svg?branch=master)](http://inch-ci.org/github/seblindberg/ruby-linked)
data/lib/linked/item.rb CHANGED
@@ -56,12 +56,12 @@ module Linked
56
56
  @prev = nil
57
57
  end
58
58
  end
59
-
59
+
60
60
  # Calling #dup on an item returns a copy that is no longer connected to the
61
61
  # original item chain, or the list. The value will also be copied.
62
62
  #
63
63
  # Returns a new Item.
64
-
64
+
65
65
  def initialize_dup(source)
66
66
  @next = @prev = @list = nil
67
67
  @value = begin
@@ -326,21 +326,21 @@ module Linked
326
326
  item = item.next
327
327
  end
328
328
  end
329
-
329
+
330
330
  # Freezes the value, as well as making the list item itself immutable.
331
-
331
+
332
332
  def freeze
333
333
  value.freeze
334
334
  super
335
335
  end
336
-
336
+
337
337
  # The default #inspect method becomes very cluttered the moment you start
338
338
  # liking objects together. This implementation fixes that and only shows the
339
339
  # class name, object id and value (if set).
340
-
340
+
341
341
  def inspect
342
342
  return yield self if block_given?
343
-
343
+
344
344
  output = format '%s:0x%0x', self.class.name, object_id
345
345
  value ? output + " value=#{value.inspect}" : output
346
346
  end
data/lib/linked/list.rb CHANGED
@@ -46,67 +46,81 @@ module Linked
46
46
  def initialize(*)
47
47
  @eol = EOL.new list: self
48
48
  @item_count = 0
49
-
49
+
50
50
  super
51
51
  end
52
-
52
+
53
53
  # When copying a list its entire item chain needs to be copied as well.
54
54
  # Therefore #dup will be called on each of the original lists items, making
55
55
  # this operation quite expensive.
56
-
56
+
57
57
  def initialize_dup(source)
58
58
  @eol = EOL.new list: self
59
59
  @item_count = 0
60
-
60
+
61
61
  source.each_item { |item| push item.dup }
62
-
62
+
63
63
  super
64
64
  end
65
65
 
66
- # Access the first n item(s) in the list.
66
+ # Access the first n item(s) in the list. If a block is given each item will
67
+ # be yielded to it. The first item, starting from the first in the list, for
68
+ # which the block returns true and the n - 1 items directly following it
69
+ # will be returned.
67
70
  #
68
71
  # n - the number of items to return.
69
72
  #
70
- # Returns the first item, or an array of items if n > 1.
73
+ # Returns, for different values of n:
74
+ # n == 0) nil
75
+ # n == 1) an item if the list contains one, or nil
76
+ # n > 1) an array of between 0 and n items, depending on how many are in
77
+ # the list
71
78
 
72
- def first(*args)
73
- if args.empty?
74
- eol.next!
75
- else
76
- super
79
+ def first(n = 1)
80
+ raise ArgumentError, 'n cannot be negative' if n < 0
81
+
82
+ return first_item_after eol, count, n unless block_given?
83
+
84
+ item = eol
85
+ items_left = count
86
+
87
+ items_left.times do
88
+ break if yield next_item = item.next
89
+ item = next_item
90
+ items_left -= 1
77
91
  end
92
+
93
+ first_item_after item, items_left, n
78
94
  end
79
95
 
80
- # Access the last n item(s) in the list. When n > 1 the resulting array of
81
- # items will have their order preserved.
82
- #
83
- # When n is zero an empty array will be returned, in order to comply with
84
- # the behaviour of #first. Negative values will raise an ArgumentError.
96
+ # Access the last n item(s) in the list. The items will retain thier order.
97
+ # If a block is given each item, starting with the last in the list, will be
98
+ # yielded to it. The first item for which the block returns true and the
99
+ # n - 1 items directly preceding it will be returned.
85
100
  #
86
101
  # n - the number of items to return.
87
102
  #
88
- # Returns the last item, or an array of items if n > 1.
103
+ # Returns, for different values of n:
104
+ # n == 0) nil
105
+ # n == 1) an item if the list contains one, or nil
106
+ # n > 1) an array of between 0 and n items, depending on how many are in
107
+ # the list
89
108
 
90
109
  def last(n = 1)
91
- if n == 1
92
- eol.prev!
93
- else
94
- raise ArgumentError, 'n cannot be negative' if n < 0
95
-
96
- n = count if n > count
97
- res = Array.new n
110
+ raise ArgumentError, 'n cannot be negative' if n < 0
98
111
 
99
- return res if n == 0
112
+ return last_item_before eol, count, n unless block_given?
100
113
 
101
- item = eol.prev!
102
- loop do
103
- n -= 1
104
- res[n] = item
105
- item = item.prev
106
- end
114
+ item = eol
115
+ items_left = count
107
116
 
108
- res
117
+ items_left.times do
118
+ break if yield prev_item = item.prev
119
+ item = prev_item
120
+ items_left -= 1
109
121
  end
122
+
123
+ last_item_before item, items_left, n
110
124
  end
111
125
 
112
126
  # Overrides the Enumerable#count method when given no argument to provide a
@@ -184,21 +198,32 @@ module Linked
184
198
  # Iterates over each item in the list, either in normal or reverse order. If
185
199
  # a block is not given an enumerator is returned.
186
200
  #
187
- # reverse - flips the iteration order if true.
201
+ # reverse - flips the iteration order if true. Note that this option is
202
+ # depricated and will be removed in the next major release.
188
203
 
189
204
  def each_item(reverse: false, &block)
190
205
  if reverse
206
+ warn '[DEPRECATION] the option `reverse: true` will be removed in a future release. Please call `reverse_each_item` instead.'
191
207
  eol.before(&block)
192
208
  else
193
209
  eol.after(&block)
194
210
  end
195
211
  end
196
-
212
+
197
213
  alias each each_item
198
-
214
+
215
+ # Iterates over each item in the list in reverse order. If a block is not
216
+ # given an enumerator is returned.
217
+
218
+ def reverse_each_item(&block)
219
+ eol.before(&block)
220
+ end
221
+
222
+ alias reverse_each reverse_each_item
223
+
199
224
  # Calls #freeze on all items in the list, as well as the head and the tail
200
225
  # (eol).
201
-
226
+
202
227
  def freeze
203
228
  eol.freeze
204
229
  each_item(&:freeze)
@@ -214,15 +239,15 @@ module Linked
214
239
  def inspect(&block)
215
240
  # Get the parents inspect output
216
241
  res = [super]
217
-
242
+
218
243
  each_item do |item|
219
244
  lines = item.inspect(&block).split "\n"
220
-
245
+
221
246
  res.push (item.last? ? '└─╴' : '├─╴') + lines.shift
222
247
  padding = item.last? ? '   ' : '│  '
223
248
  lines.each { |line| res.push padding + line }
224
249
  end
225
-
250
+
226
251
  res.join("\n")
227
252
  end
228
253
 
@@ -247,5 +272,60 @@ module Linked
247
272
  private def shrink(n = 1)
248
273
  @item_count -= n
249
274
  end
275
+
276
+ # Private helper method that returns the first n items, starting just after
277
+ # item, given that there are items_left items left. The following must hold
278
+ # for the output to be valid:
279
+ # a) n > 0
280
+ # b) there are at least items_left items left
281
+ #
282
+ # item - the Item just before the item to start from
283
+ # items_left - the number of items left.
284
+ # n - the number of items to return.
285
+ #
286
+ # Returns, for different values of n:
287
+ # n == 0) nil
288
+ # n == 1) an item if items_left > 0 or nil
289
+ # n > 1) an array of items if items_left > 0 or an empty array
290
+
291
+ private def first_item_after(item, items_left, n)
292
+ # Optimize for these cases
293
+ return nil if n == 0
294
+ return item.next if n == 1
295
+
296
+ (n > items_left ? items_left : n).times.map { item = item.next }
297
+ rescue StopIteration
298
+ n > 1 ? [] : nil
299
+ end
300
+
301
+ # Private helper method that returns the last n items, ending just before
302
+ # item, given that there are items_left items left. The following must hold
303
+ # for the output to be valid:
304
+ # a) n > 0
305
+ # b) there are at least items_left items left
306
+ #
307
+ # item - the Item just after the item to start from.
308
+ # items_left - the number of items left.
309
+ # n - the number of items to return.
310
+ #
311
+ # Returns, for different values of n:
312
+ # n == 0) nil
313
+ # n == 1) an item if items_left > 0 or nil
314
+ # n > 1) an array of items if items_left > 0 or an empty array
315
+
316
+ private def last_item_before(item, items_left, n)
317
+ # Optimize for these cases
318
+ return nil if n == 0
319
+ return item.prev if n == 1
320
+
321
+ # Truncate n if it is larger than the number of items
322
+ # left
323
+ n = (n > items_left ? items_left : n)
324
+ (n - 1).downto(0).with_object(Array.new n) do |i, arr|
325
+ arr[i] = item = item.prev
326
+ end
327
+ rescue StopIteration
328
+ n > 1 ? [] : nil
329
+ end
250
330
  end
251
331
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Linked
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linked
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Lindberg
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-07 00:00:00.000000000 Z
11
+ date: 2016-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler