rooted_tree 0.2.1 → 0.2.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: bf70759dc7a2bf845496a1eb2291a91a4a60e5e2
4
- data.tar.gz: 6e7365e5d05e9f8daa1b34e5c726f0d2d8865d1b
3
+ metadata.gz: 22a5b2a13278deccce0118fecd19ba5d65e39a4c
4
+ data.tar.gz: f2de5a5dba41d23f396e325889f9ed2dd6d468af
5
5
  SHA512:
6
- metadata.gz: 10622361191c35e83775a11d129245eaebc2ce0b69f970e24195dd20bba065784a53a29295446c733d7bd3179b74302a29fe83fd5da6b48fbcfd8c573310db86
7
- data.tar.gz: 1e9c114ae888537459a66f2c7b1f27212c2d20160c35a9e84c7a111916c14d20f6042feb585e6430e18cce600a79b0177b7cb0f932e59b26c6f020f8d3ef25f7
6
+ metadata.gz: 492a612d75f800c8e3ab638beb1c7bc9f352125eb29ceff47bf2a38855b12bbbb4675846dd52a4813877baf5402da1f39a6b53880c2c9adf9083621c50122dc7
7
+ data.tar.gz: cd0a3ef730dca13e6d083bdf44ed0b834a973121dff0ca05369fd355f8c6b30a9be1fd957dc5b9e60dd5b0ba1395964fe63122e0914a4593441b791c6b4b87f3
data/README.md CHANGED
@@ -53,22 +53,15 @@ The gem is primarily ment to be extended by other classes. The following example
53
53
 
54
54
  ```ruby
55
55
  class FileSystemItem < RootedTree::Node
56
- attr_reader :name
57
-
58
- def initialize name
59
- super()
60
- @name = name
61
- end
62
-
63
56
  def display
64
- inspect { |item| item.name }
57
+ inspect { |item| item.value }
65
58
  end
66
59
 
67
60
  def self.map_to_path path = '.', root: new(path)
68
61
  # Iterate over all of the files in the directory
69
62
  Dir[path + '/*'].each do |entry|
70
63
  # Create a new FileSystemItem for the entry
71
- item = new File.basename entry
64
+ item = new File.basename(entry)
72
65
  root << item
73
66
  # Continue to map the files and directories under
74
67
  # entry, if it is a directory
@@ -6,25 +6,19 @@ require 'rooted_tree'
6
6
  #
7
7
  # Maps the entries in the file system to `Node` objects via .map_to_path. The
8
8
  # Node#inspect method is then exploited in #display to show the resulting tree
9
- # structure.
9
+ # structure. The name of each entry in the filesystem is stored in the value
10
+ # field of the Node.
10
11
 
11
12
  class FileSystemItem < RootedTree::Node
12
- attr_reader :name
13
-
14
- def initialize name
15
- super()
16
- @name = name
17
- end
18
-
19
13
  def display
20
- inspect { |item| item.name }
14
+ inspect { |item| item.value }
21
15
  end
22
16
 
23
17
  def self.map_to_path path = '.', root: new(path)
24
18
  # Iterate over all of the files in the directory
25
19
  Dir[path + '/*'].each do |entry|
26
20
  # Create a new FileSystemItem for the entry
27
- item = new File.basename entry
21
+ item = new File.basename(entry)
28
22
  root << item
29
23
  # Continue to map the files and directories under
30
24
  # entry, if it is a directory
@@ -23,21 +23,27 @@
23
23
  module RootedTree
24
24
  class Node
25
25
  include Enumerable
26
-
27
- attr_accessor :first_child, :last_child, :degree
26
+
27
+ attr_accessor :first_child, :last_child, :degree, :value
28
28
  attr_writer :next, :prev, :parent
29
-
29
+
30
30
  protected :next=, :prev=, :parent=, :first_child=, :last_child=, :degree=
31
-
31
+
32
32
  alias arity degree
33
33
 
34
- def initialize
34
+ def self.[](value = nil)
35
+ return value if value.is_a? self
36
+ self.new value
37
+ end
38
+
39
+ def initialize value = nil
35
40
  @parent = nil
36
41
  @next = nil
37
42
  @prev = nil
38
43
  @first_child = nil
39
44
  @last_child = nil
40
45
  @degree = 0
46
+ @value = value
41
47
  end
42
48
 
43
49
  def initialize_copy(*)
@@ -48,9 +54,10 @@ module RootedTree
48
54
  @first_child = duped_children.first
49
55
  @last_child = duped_children.last
50
56
  end
51
-
57
+
52
58
  def freeze
53
59
  super
60
+ @value.freeze
54
61
  children.each(&:freeze)
55
62
  end
56
63
 
@@ -85,7 +92,7 @@ module RootedTree
85
92
 
86
93
  def root
87
94
  return self if root?
88
-
95
+
89
96
  node = self
90
97
  loop { node = node.parent }
91
98
  node
@@ -116,15 +123,15 @@ module RootedTree
116
123
  end
117
124
 
118
125
  alias level depth
119
-
126
+
120
127
  # Max Depth
121
128
  #
122
129
  # Returns the maximum node depth under this node.
123
-
124
- def max_depth offset = depth
130
+
131
+ def max_depth(offset = depth)
125
132
  return offset if leaf?
126
-
127
- children.map {|c| c.max_depth offset + 1 }.max
133
+
134
+ children.map { |c| c.max_depth offset + 1 }.max
128
135
  end
129
136
 
130
137
  # Max Degree
@@ -179,14 +186,15 @@ module RootedTree
179
186
  #
180
187
  # Insert a child between this node and the one after it.
181
188
 
182
- def append_sibling(node)
189
+ def append_sibling(value = nil)
183
190
  raise StructureException, 'Root node can not have siblings' if root?
184
191
 
192
+ node = self.class[value]
185
193
  node.next = @next
186
194
  node.prev = self
187
195
  node.parent = @parent
188
196
  @parent.degree += 1
189
-
197
+
190
198
  if @next
191
199
  @next.prev = node
192
200
  else
@@ -199,14 +207,15 @@ module RootedTree
199
207
  #
200
208
  # Insert a child between this node and the one before it.
201
209
 
202
- def prepend_sibling(node)
210
+ def prepend_sibling(value = nil)
203
211
  raise StructureException, 'Root node can not have siblings' if root?
204
212
 
213
+ node = self.class[value]
205
214
  node.next = self
206
215
  node.prev = @prev
207
216
  node.parent = @parent
208
217
  @parent.degree += 1
209
-
218
+
210
219
  if @prev
211
220
  @prev.next = node
212
221
  else
@@ -214,41 +223,42 @@ module RootedTree
214
223
  end
215
224
  @prev = node
216
225
  end
217
-
218
- private def add_child_to_leaf(child)
219
- @first_child = @last_child = child
220
- child.next = child.prev = nil
226
+
227
+ private def add_child_to_leaf(value)
228
+ node = self.class[value]
229
+ @first_child = @last_child = node
230
+ node.next = node.prev = nil
221
231
  @degree = 1
222
- child.parent = self
232
+ node.parent = self
223
233
  end
224
234
 
225
235
  # Append Child
226
236
  #
227
237
  # Insert a child after the last one.
228
238
 
229
- def append_child(child)
239
+ def append_child(value = nil)
230
240
  if leaf?
231
- add_child_to_leaf child
241
+ add_child_to_leaf value
232
242
  else
233
- @last_child.append_sibling child
243
+ @last_child.append_sibling value
234
244
  end
235
245
  self
236
246
  end
237
247
 
248
+ alias << append_child
249
+
238
250
  # Prepend Child
239
251
  #
240
252
  # Insert a child before the first one.
241
253
 
242
- def prepend_child(child)
254
+ def prepend_child(value = nil)
243
255
  if leaf?
244
- add_child_to_leaf child
256
+ add_child_to_leaf value
245
257
  else
246
- @first_child.prepend_sibling child
258
+ @first_child.prepend_sibling value
247
259
  end
248
260
  end
249
261
 
250
- alias << append_child
251
-
252
262
  # Extract
253
263
  #
254
264
  # Extracts the node and its subtree from the larger structure.
@@ -303,7 +313,8 @@ module RootedTree
303
313
  # Children
304
314
  #
305
315
  # Yields to each of the node children. The default order is left-to-right,
306
- # but by passing rtl: true the order can be reversed. If a block is not given an enumerator is returned.
316
+ # but by passing rtl: true the order can be reversed. If a block is not
317
+ # given an enumerator is returned.
307
318
  #
308
319
  # Note that the block will catch any StopIteration that is raised and
309
320
  # terminate early, returning the value of the exception.
@@ -324,6 +335,33 @@ module RootedTree
324
335
  end
325
336
  end
326
337
 
338
+ # Child
339
+ #
340
+ # Accessor method for any of the n children under this node.
341
+
342
+ def child(n = nil)
343
+ if n.nil?
344
+ if @degree != 1
345
+ raise ArgumentError, 'No argument given for node with degree != 1'
346
+ end
347
+ return @first_child
348
+ end
349
+
350
+ rtl = if n < 0
351
+ n = -1 - n
352
+ true
353
+ else
354
+ false
355
+ end
356
+
357
+ raise RangeError, 'Child index out of range' if n >= @degree
358
+
359
+ children(rtl: rtl).each do |c|
360
+ break c if n == 0
361
+ n -= 1
362
+ end
363
+ end
364
+
327
365
  # Each
328
366
  #
329
367
  # Yields first to self and then to each child. If a block is not given an
@@ -382,37 +420,37 @@ module RootedTree
382
420
 
383
421
  children.to_a == other.children.to_a
384
422
  end
385
-
423
+
386
424
  # Tree!
387
425
  #
388
426
  # Wraps the entire tree in a Tree object. The operation will freeze the node
389
427
  # structure, making it immutable. If this node is a child the root will be
390
428
  # found and passed to Tree.new.
391
-
429
+
392
430
  def tree!
393
431
  Tree.new root
394
432
  end
395
-
433
+
396
434
  # Tree
397
435
  #
398
436
  # Duplicates the entire tree and calls #tree! on the copy.
399
-
437
+
400
438
  def tree
401
439
  root.dup.tree!
402
440
  end
403
-
441
+
404
442
  # Subtree!
405
443
  #
406
444
  # Extracts this node from the larger tree and wraps it in a Tree object.
407
-
445
+
408
446
  def subtree!
409
447
  Tree.new extract
410
448
  end
411
-
449
+
412
450
  # Subtree
413
451
  #
414
452
  # Duplicates this node and its descendants and wraps them in a Tree object.
415
-
453
+
416
454
  def subtree
417
455
  Tree.new dup
418
456
  end
@@ -3,30 +3,30 @@
3
3
  module RootedTree
4
4
  class Tree
5
5
  attr_reader :root
6
-
6
+
7
7
  def initialize(node)
8
8
  @root = node.root
9
9
  @root.freeze
10
10
  end
11
-
11
+
12
12
  def tree
13
13
  self
14
14
  end
15
-
15
+
16
16
  # Degree
17
17
  #
18
18
  # Returns the maximum degree (number of children) in the tree.
19
-
19
+
20
20
  def degree
21
21
  @degree ||= root.max_degree
22
22
  end
23
-
23
+
24
24
  # Depth
25
25
  #
26
26
  # Returns the maximum depth of the tree.
27
-
27
+
28
28
  def depth
29
29
  @depth ||= root.max_depth
30
30
  end
31
31
  end
32
- end
32
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RootedTree
4
- VERSION = '0.2.1'
4
+ VERSION = '0.2.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rooted_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.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-07-23 00:00:00.000000000 Z
11
+ date: 2016-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler