modular_tree 0.0.1 → 0.0.3

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
  SHA256:
3
- metadata.gz: 87b4426ea3d2f00ff5959831b0297d21190fee942d720f9e239cccc74e02ddcb
4
- data.tar.gz: feb82cbe67f18d2f0855f041a4612fbe023ae5564706123dee7bbef1e0d39b4a
3
+ metadata.gz: 1b145f3b7daeb0bddc2a2415e3a98d6d6232d95afeca8147908bffa2089ff412
4
+ data.tar.gz: 68271887a655b0196e5f9819f72ee80ca9e853c15568ab48cc1d7e15c4a29d22
5
5
  SHA512:
6
- metadata.gz: ef3db04b865ec12612ccae42104bad67344892857f3bed8b523cc70b4aaab9ace7675cbb30bfab751143c741d0e45c13157cc6f8594b90f296fb4e2fb0efe15a
7
- data.tar.gz: dc1b4179bf2f46d3506af4c8660d71d552ff07567dda93403a5eca618744ca1a2aa53f8adf7f89d251d9b9f3ea4acb3080df4bd0933b4b33840656e8f874fc00
6
+ metadata.gz: b9a39254ef102c23dbba9445b5b95b3d925d0954ef28de91107318c24ce9c450dd1fc2612cae18fc2c4033314bcd85b14a7126eb09e01daee076e380b05fe54c
7
+ data.tar.gz: 3b84c591c7816199835041074b6fb8b9506c5b85b438000045ce4d21627559835edeadf0336ca6635d76cef563082254318a1cf13d15342c431f407f51868615
@@ -63,11 +63,21 @@ module Tree
63
63
  # Implementation of Enumerable#each extended with filters. The block is
64
64
  # called with value, key, and parent as arguments (it may choose to
65
65
  # ignore key and/or parent). Returns an enumerator of values without a block
66
- def each(*filter, this: true, &block) = common_each(*filter, :value, :each_preorder, this, &block)
66
+ def each(*filter, this: true, &block) = common_each(*filter, :value, :do_each_preorder, this, &block)
67
+
68
+ # Implementation of Enumerable#select extended with a single filter. As
69
+ # #each, the block is called with value, key, and parent arguments
70
+ def select(filter = nil, this: true, &block)
71
+ if block_given?
72
+ each(block, true, this: this).to_a
73
+ else
74
+ each(filter || true, true, this: this)
75
+ end
76
+ end
67
77
 
68
78
  # Like #each but the block is called with node, key, and parent instead of
69
79
  # value, key, and parent
70
- def nodes(*filter, this: true, &block) = common_each(*filter, :node, :each_preorder, this, &block)
80
+ def nodes(*filter, this: true, &block) = common_each(*filter, :node, :do_each_preorder, this, &block)
71
81
 
72
82
  # Pre-order enumerator of selected nodes. Same as #each without a block
73
83
  def preorder(*filter, this: true) = each(*filter, this: this)
@@ -6,9 +6,9 @@ module Tree
6
6
  # traverse expression decides if the child nodes should be traversed
7
7
  # recursively
8
8
  #
9
- # The expressions can be a Proc, Symbol, or an array of classes. In
10
- # addition, +select+ can also be true, and +traverse+ can be true,
11
- # false, or nil. True, false, and nil have special meanings:
9
+ # The expressions can be a Proc, Symbol, Class, or an array of classes. In
10
+ # addition, +select+ can be true, and +traverse+ can be true, false, or
11
+ # nil. These values have special meanings:
12
12
  #
13
13
  # when +select+ is
14
14
  # true Select always. This is the default
@@ -17,14 +17,17 @@ module Tree
17
17
  # true Traverse always. This is the default
18
18
  # false Traverse only if select didn't match
19
19
  # nil Expects +select+ to return a two-tuple of booleans. Can't be
20
- # used when +select+ is true
20
+ # used when +select+ is true. TODO: Explain
21
21
  #
22
22
  # If the expression is a Proc object, it will be called with the current
23
23
  # node as argument. If the return value is true, the node is
24
24
  # selected/traversed and skipped otherwise. If the expression is a method
25
25
  # name (Symbol), the method will be called on each node with no arguments.
26
- # It is not an error if the method doesn't exists but the node is not
27
- # selected/traversed
26
+ # It is not an error if the method doesn't exists on the a given node but
27
+ # the node is not selected/traversed
28
+ #
29
+ # If the expression is a class or an array of classes, a given node matches
30
+ # if it is an instance of one of the classes or any subclass
28
31
  #
29
32
  # Filters should not have side-effects because they can be used in
30
33
  # enumerators that doesn't execute the filter unless the enumerator is
@@ -69,7 +69,7 @@ module Tree
69
69
 
70
70
  def node = array
71
71
  def this = array.first
72
- def value = array.first
72
+ def value = array.first # FIXME What is this? It is a problem several places
73
73
 
74
74
  attr_accessor :array
75
75
 
@@ -167,6 +167,33 @@ module Tree
167
167
 
168
168
  def each_child(&block) = @children.map(&block)
169
169
  def attach(child) = @children << child
170
+
171
+ # Can be used with any array implementation
172
+ def insert(where, child) = insert_append(:insert, where, child)
173
+ def append(where, child) = insert_append(:append, where, child)
174
+
175
+ def replace(where, *children)
176
+ children = Array(children).flatten
177
+ case where
178
+ when Integer
179
+ subject = @children[where] or raise ArgumentError
180
+ index = where
181
+ else
182
+ subject = where
183
+ index = @children.index(where) or raise ArgumentError
184
+ end
185
+ @children = @children[0...index] + children + @children[index + 1..-1]
186
+ subject
187
+ end
188
+
189
+ protected
190
+ def insert_append(which, where, child)
191
+ if !where.is_a?(Integer)
192
+ where = @children.index(where) or raise ArgumentError, "Can't find object"
193
+ end
194
+ where += 1 if which == :append
195
+ @children.insert(where, child)
196
+ end
170
197
  end
171
198
 
172
199
  module InternalChildrenHashImplementation
@@ -198,5 +225,28 @@ module Tree
198
225
  child.send(:parent=, self)
199
226
  end
200
227
  end
228
+
229
+ module InternalParentChildArrayImplementation
230
+ include InternalParentChildImplementation
231
+
232
+ def insert(where, child)
233
+ super
234
+ child.send(:parent=, self)
235
+ end
236
+
237
+ def append(where, child)
238
+ super
239
+ child.send(:parent=, self)
240
+ end
241
+
242
+ # Requires that Child classes already has defined this
243
+ def replace(where, *children)
244
+ children = Array(children).flatten
245
+ subject = super(where, children)
246
+ subject.send(:parent=, nil)
247
+ children.each { |child| child.send(:parent=, self) }
248
+ subject
249
+ end
250
+ end
201
251
  end
202
252
 
@@ -36,6 +36,10 @@ module Tree
36
36
  def attach(child) = abstract_method
37
37
  end
38
38
 
39
+ # TODO
40
+ module ParentChildProperty
41
+ end
42
+
39
43
  module KeyProperty # Set
40
44
  def key = abstract_method
41
45
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tree
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.3"
5
5
  end
data/lib/modular_tree.rb CHANGED
@@ -39,9 +39,10 @@ module Tree
39
39
  class ArrayTree < AbstractTree # Aka. SetTree aka. Tree
40
40
  include InternalParentImplementation
41
41
  include InternalChildrenArrayImplementation
42
- include InternalParentChildImplementation
42
+ include InternalParentChildArrayImplementation
43
43
  include UpTreeAlgorithms
44
44
  include DownTreeAlgorithms
45
+ include DownTreeFilteredAlgorithms
45
46
 
46
47
  def self.filter(*args) = DownTreeAlgorithms.filter(*args)
47
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modular_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen