metaractor-sycamore 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09edde479077bf32f656d467d8ff8a570d74bd6175bab55aa15946e366938efc'
4
- data.tar.gz: 85aca0da2093c00c5eefc2c76341d5442356e6625113543d2374b97de07fcadd
3
+ metadata.gz: ae5565f1e3e26149ac616264c7f80814ec43d0402af467d3bd39a0a95a242007
4
+ data.tar.gz: 6ac8b42b9cbfd6b1c2bbb32bb5415ca0f099d40c3cced190e264297f215414ea
5
5
  SHA512:
6
- metadata.gz: b118f12ebd537dd56965309b610e9588b9b39eb7dd228e9b909fb7a67812e6335e163d1a4b679fad0a9e093f86a8919e20548c3edafce3a0179b42a4b0eef60b
7
- data.tar.gz: ad88b3e9d45fa3429de8d27a091412e099d38e6606118a40cff6d2ffde9b963f9076f770395855459b2ec1974c3ad982a42fae94facfaa7fef8bc39218f3e9a4
6
+ metadata.gz: 31278db416f78913b21d63f384b5a02e195d3d47ceb6a91a847fd0489b99c7164bfc7c0629e046eabe8ee629a3de7006c684da9fd8f7e32e3cdfd86b3bb4169a
7
+ data.tar.gz: 1e2e022767207c83f0fd3da132a11e67f9dcc866140ac3751e1624b737a994a0c2e87856363b95ae0d84033b531f35a6d86533537f86df58822abf89714ce223
data/Gemfile CHANGED
@@ -1,12 +1,12 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
5
  group :debug do
6
- gem 'guard-rspec'
7
- gem 'pry'
6
+ gem "guard-rspec"
7
+ gem "pry"
8
8
  end
9
9
 
10
10
  group :test do
11
- gem 'coveralls', require: false, platform: :mri
11
+ gem "coveralls", require: false, platform: :mri
12
12
  end
data/Rakefile CHANGED
@@ -1,36 +1,35 @@
1
- require 'bundler/gem_tasks'
1
+ require "bundler/gem_tasks"
2
2
 
3
3
  begin
4
- require 'rspec/core/rake_task'
4
+ require "rspec/core/rake_task"
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
  rescue LoadError
7
7
  puts "Couldn't find RSpec core Rake task"
8
8
  end
9
9
 
10
10
  begin
11
- require 'yard'
11
+ require "yard"
12
12
  YARD::Rake::YardocTask.new do |t|
13
- t.options = ['--verbose']
14
- t.files = ['lib/**/*.rb', 'doc/**/*.md']
15
- t.stats_options = ['--list-undoc']
13
+ t.options = ["--verbose"]
14
+ t.files = ["lib/**/*.rb", "doc/**/*.md"]
15
+ t.stats_options = ["--list-undoc"]
16
16
  end
17
17
  rescue LoadError
18
18
  puts "Couldn't find YARD"
19
19
  end
20
20
 
21
21
  begin
22
- require 'yard-doctest'
22
+ require "yard-doctest"
23
23
  YARD::Doctest::RakeTask.new do |task|
24
24
  task.doctest_opts = %w[]
25
- task.pattern = 'lib/**/*.rb'
25
+ task.pattern = "lib/**/*.rb"
26
26
  end
27
27
  rescue LoadError
28
28
  puts "Couldn't find yard-doctest"
29
29
  end
30
30
 
31
- task :default =>
32
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
33
- [:spec]
34
- else
35
- [:spec, 'yard:doctest']
36
- end
31
+ task default: if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
32
+ [:spec]
33
+ else
34
+ [:spec, "yard:doctest"]
35
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.2
1
+ 0.4.3
@@ -1,7 +1,6 @@
1
- require 'delegate'
1
+ require "delegate"
2
2
 
3
3
  module Sycamore
4
-
5
4
  ##
6
5
  # An Absence object represents the absence of a specific child {Sycamore::Tree}.
7
6
  #
@@ -21,7 +20,6 @@ module Sycamore
21
20
  # implementation of the parent tree and the parent node.
22
21
  #
23
22
  class Absence < Delegator
24
-
25
23
  ##
26
24
  # @api private
27
25
  #
@@ -30,7 +28,7 @@ module Sycamore
30
28
  end
31
29
 
32
30
  class << self
33
- alias at new
31
+ alias_method :at, :new
34
32
  end
35
33
 
36
34
  ########################################################################
@@ -46,7 +44,7 @@ module Sycamore
46
44
  @tree or Nothing
47
45
  end
48
46
 
49
- alias __getobj__ presence
47
+ alias_method :__getobj__, :presence
50
48
 
51
49
  ##
52
50
  # @api private
@@ -96,17 +94,17 @@ module Sycamore
96
94
  if absent?
97
95
  # TODO: This is duplication of Tree#child_at! How can we remove it, without introducing a module for this single method or inherit from Tree?
98
96
  case path.length
99
- when 0 then raise ArgumentError, 'wrong number of arguments (given 0, expected 1+)'
100
- when 1 then child_of(*path)
101
- else child_of(path[0]).child_at(*path[1..-1])
97
+ when 0 then raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
98
+ when 1 then child_of(*path)
99
+ else child_of(path[0]).child_at(*path[1..])
102
100
  end
103
101
  else
104
102
  presence.child_at(*path)
105
103
  end
106
104
  end
107
105
 
108
- alias [] child_at
109
- alias dig child_at
106
+ alias_method :[], :child_at
107
+ alias_method :dig, :child_at
110
108
 
111
109
  ##
112
110
  # A developer-friendly string representation of the absent tree.
@@ -114,7 +112,7 @@ module Sycamore
114
112
  # @return [String]
115
113
  #
116
114
  def inspect
117
- "#{absent? ? 'absent' : 'present'} child of node #{@parent_node.inspect} in #{@parent_tree.inspect}"
115
+ "#{absent? ? "absent" : "present"} child of node #{@parent_node.inspect} in #{@parent_tree.inspect}"
118
116
  end
119
117
 
120
118
  ##
@@ -174,6 +172,5 @@ module Sycamore
174
172
  end
175
173
  end
176
174
  end
177
-
178
175
  end
179
176
  end
@@ -1,16 +1,16 @@
1
1
  module Sycamore
2
2
  # raised when a value is not a valid node
3
- class InvalidNode < ArgumentError ; end
3
+ class InvalidNode < ArgumentError; end
4
4
 
5
5
  # raised when trying to call a additive command method of the {Nothing} tree
6
- class NothingMutation < StandardError ; end
6
+ class NothingMutation < StandardError; end
7
7
 
8
8
  # raised when calling {Tree#node} or {Tree#node!} on a Tree with multiple nodes
9
- class NonUniqueNodeSet < StandardError ; end
9
+ class NonUniqueNodeSet < StandardError; end
10
10
 
11
11
  # raised when calling {Tree#node!} on a Tree without nodes
12
- class EmptyNodeSet < StandardError ; end
12
+ class EmptyNodeSet < StandardError; end
13
13
 
14
14
  # raised when trying to fetch the child of a leaf
15
- class ChildError < KeyError ; end
15
+ class ChildError < KeyError; end
16
16
  end
@@ -1,4 +1,4 @@
1
- require 'sycamore/nothing'
1
+ require "sycamore/nothing"
2
2
 
3
3
  # optional global shortcut constant for {Sycamore::Nothing}
4
4
  Nothing = Sycamore::Nothing unless defined? Nothing
@@ -1,4 +1,4 @@
1
- require 'sycamore'
1
+ require "sycamore"
2
2
 
3
3
  # optional global shortcut constant for Sycamore::Path
4
4
  Path = Sycamore::Path
@@ -1,4 +1,4 @@
1
- require 'sycamore'
1
+ require "sycamore"
2
2
 
3
3
  # optional global shortcut constant for Sycamore::Tree
4
4
  Tree = Sycamore::Tree
@@ -1,2 +1,2 @@
1
- require 'sycamore/extension/tree'
2
- require 'sycamore/extension/nothing'
1
+ require "sycamore/extension/tree"
2
+ require "sycamore/extension/nothing"
@@ -1,7 +1,6 @@
1
- require 'singleton'
1
+ require "singleton"
2
2
 
3
3
  module Sycamore
4
-
5
4
  ##
6
5
  # The Nothing Tree singleton class.
7
6
  #
@@ -43,7 +42,7 @@ module Sycamore
43
42
  # TODO: YARD should be informed about this method definitions.
44
43
  command_methods.each do |command_method|
45
44
  define_method command_method do |*args|
46
- raise NothingMutation, 'attempt to change the Nothing tree'
45
+ raise NothingMutation, "attempt to change the Nothing tree"
47
46
  end
48
47
  end
49
48
 
@@ -66,7 +65,7 @@ module Sycamore
66
65
  # @return [String]
67
66
  #
68
67
  def to_s
69
- 'Tree[Nothing]'
68
+ "Tree[Nothing]"
70
69
  end
71
70
 
72
71
  ##
@@ -75,7 +74,7 @@ module Sycamore
75
74
  # @return [String]
76
75
  #
77
76
  def inspect
78
- '#<Sycamore::Nothing>'
77
+ "#<Sycamore::Nothing>"
79
78
  end
80
79
 
81
80
  def freeze
@@ -95,7 +94,6 @@ module Sycamore
95
94
  (other.is_a?(Tree) or other.is_a?(Absence)) and other.empty?
96
95
  end
97
96
 
98
-
99
97
  ########################################################################
100
98
  # Falsiness
101
99
  #
@@ -119,7 +117,6 @@ module Sycamore
119
117
  # true
120
118
  # end
121
119
 
122
-
123
120
  ########################################################################
124
121
  # Some helpers
125
122
  #
@@ -139,19 +136,17 @@ module Sycamore
139
136
  include Singleton
140
137
 
141
138
  def inspect
142
- 'n/a'
139
+ "n/a"
143
140
  end
144
141
  end
145
142
 
146
143
  ##
147
144
  # @api private
148
145
  NestedString = NestedStringPresentation.instance.freeze
149
-
150
146
  end
151
147
 
152
148
  ############################################################################
153
149
  # The Nothing Tree Singleton object
154
150
  #
155
151
  Nothing = NothingTree.instance.freeze
156
-
157
152
  end
data/lib/sycamore/path.rb CHANGED
@@ -1,7 +1,6 @@
1
- require 'forwardable'
1
+ require "forwardable"
2
2
 
3
3
  module Sycamore
4
-
5
4
  ##
6
5
  # A compact, immutable representation of Tree paths, i.e. node sequences.
7
6
  #
@@ -62,7 +61,7 @@ module Sycamore
62
61
  #
63
62
  def self.of(*args)
64
63
  if (parent = args.first).is_a? Path
65
- parent.branch(*args[1..-1])
64
+ parent.branch(*args[1..])
66
65
  else
67
66
  root.branch(*args)
68
67
  end
@@ -71,7 +70,7 @@ module Sycamore
71
70
  class << self
72
71
  private :new # disable Path.new
73
72
 
74
- alias [] of
73
+ alias_method :[], :of
75
74
  end
76
75
 
77
76
  ########################################################################
@@ -96,7 +95,7 @@ module Sycamore
96
95
  # Sycamore::Path[:foo, :bar, :baz, :qux] # => true
97
96
  #
98
97
  def branch(*nodes)
99
- return branch(*nodes.first) if nodes.size == 1 and nodes.first.is_a? Enumerable
98
+ return branch(*nodes.first) if nodes.size == 1 && nodes.first.is_a?(Enumerable)
100
99
 
101
100
  parent = self
102
101
  nodes.each do |node|
@@ -108,8 +107,8 @@ module Sycamore
108
107
  parent
109
108
  end
110
109
 
111
- alias + branch
112
- alias / branch
110
+ alias_method :+, :branch
111
+ alias_method :/, :branch
113
112
 
114
113
  ##
115
114
  # @return [Path] the n-th last parent path
@@ -126,9 +125,9 @@ module Sycamore
126
125
  distance.is_a? Integer
127
126
 
128
127
  case distance
129
- when 1 then @parent
130
- when 0 then self
131
- else parent.up(distance - 1)
128
+ when 1 then @parent
129
+ when 0 then self
130
+ else parent.up(distance - 1)
132
131
  end
133
132
  end
134
133
 
@@ -148,7 +147,7 @@ module Sycamore
148
147
  i
149
148
  end
150
149
 
151
- alias size length
150
+ alias_method :size, :length
152
151
 
153
152
  ##
154
153
  # Iterates over all nodes on this path.
@@ -160,7 +159,7 @@ module Sycamore
160
159
  # @return [Enumerator<node>]
161
160
  #
162
161
  def each_node(&block)
163
- return enum_for(__callee__) unless block_given?
162
+ return enum_for(__callee__) unless block
164
163
 
165
164
  if @parent
166
165
  @parent.each_node(&block)
@@ -168,7 +167,7 @@ module Sycamore
168
167
  end
169
168
  end
170
169
 
171
- alias each each_node
170
+ alias_method :each, :each_node
172
171
 
173
172
  ##
174
173
  # If a given structure contains this path.
@@ -184,18 +183,18 @@ module Sycamore
184
183
  def present_in?(struct)
185
184
  each do |node|
186
185
  case
187
- when struct.is_a?(Enumerable)
188
- return false unless struct.include? node
189
- struct = (Tree.like?(struct) ? struct[node] : Nothing )
190
- else
191
- return false unless struct.eql? node
192
- struct = Nothing
186
+ when struct.is_a?(Enumerable)
187
+ return false unless struct.include? node
188
+ struct = (Tree.like?(struct) ? struct[node] : Nothing)
189
+ else
190
+ return false unless struct.eql? node
191
+ struct = Nothing
193
192
  end
194
193
  end
195
194
  true
196
195
  end
197
196
 
198
- alias in? present_in?
197
+ alias_method :in?, :present_in?
199
198
 
200
199
  ########################################################################
201
200
  # @group Equality
@@ -214,8 +213,8 @@ module Sycamore
214
213
  #
215
214
  def eql?(other)
216
215
  other.is_a?(self.class) and
217
- self.length == other.length and begin
218
- i = other.each ; all? { |node| node.eql? i.next }
216
+ length == other.length and begin
217
+ i = other.each; all? { |node| node.eql? i.next }
219
218
  end
220
219
  end
221
220
 
@@ -224,8 +223,8 @@ module Sycamore
224
223
  # @param other [Object]
225
224
  #
226
225
  def ==(other)
227
- other.is_a?(Enumerable) and self.length == other.length and begin
228
- i = other.each ; all? { |node| node == i.next }
226
+ other.is_a?(Enumerable) and length == other.length and begin
227
+ i = other.each; all? { |node| node == i.next }
229
228
  end
230
229
  end
231
230
 
@@ -244,7 +243,7 @@ module Sycamore
244
243
  # Sycamore::Path[1,2,3].join # => '/1/2/3'
245
244
  # Sycamore::Path[1,2,3].join('|') # => '|1|2|3'
246
245
  #
247
- def join(separator = '/')
246
+ def join(separator = "/")
248
247
  @parent.join(separator) + separator + node.to_s
249
248
  end
250
249
 
@@ -259,8 +258,7 @@ module Sycamore
259
258
  # @return [String] a more verbose string representation of this path
260
259
  #
261
260
  def inspect
262
- "#<Sycamore::Path[#{each_node.map(&:inspect).join(',')}]>"
261
+ "#<Sycamore::Path[#{each_node.map(&:inspect).join(",")}]>"
263
262
  end
264
263
  end
265
-
266
264
  end
@@ -1,4 +1,4 @@
1
- require 'singleton'
1
+ require "singleton"
2
2
 
3
3
  module Sycamore
4
4
  class Path
@@ -25,16 +25,16 @@ module Sycamore
25
25
  0
26
26
  end
27
27
 
28
- def join(delimiter = '/')
29
- ''
28
+ def join(delimiter = "/")
29
+ ""
30
30
  end
31
31
 
32
32
  def to_s
33
- '#<Path:Root>'
33
+ "#<Path:Root>"
34
34
  end
35
35
 
36
36
  def inspect
37
- '#<Sycamore::Path::Root>'
37
+ "#<Sycamore::Path::Root>"
38
38
  end
39
39
  end
40
40
 
@@ -1,4 +1,4 @@
1
- require 'sycamore'
1
+ require "sycamore"
2
2
 
3
3
  # optional global shortcut constant for Sycamore::Tree
4
4
  STree = Sycamore::Tree
data/lib/sycamore/tree.rb CHANGED
@@ -1,12 +1,10 @@
1
1
  module Sycamore
2
-
3
2
  ##
4
3
  # A tree data structure as a recursively nested set of {#nodes nodes} of immutable values.
5
4
  #
6
5
  # See {file:README.md} for a general introduction.
7
6
  #
8
7
  class Tree
9
-
10
8
  include Enumerable
11
9
 
12
10
  # the internal hash representation of this tree
@@ -19,11 +17,11 @@ module Sycamore
19
17
 
20
18
  # the names of all command methods, which add elements to a Tree
21
19
  ADDITIVE_COMMAND_METHODS = %i[add << replace add_node_with_empty_child
22
- clear_child_of_node] << :[]=
20
+ clear_child_of_node] << :[]=
23
21
 
24
22
  # the names of all command methods, which delete elements from a Tree
25
23
  DESTRUCTIVE_COMMAND_METHODS = %i[delete >> clear compact replace
26
- clear_child_of_node] << :[]=
24
+ clear_child_of_node] << :[]=
27
25
 
28
26
  # the names of all additive command methods, which only add elements from a Tree
29
27
  PURE_ADDITIVE_COMMAND_METHODS = ADDITIVE_COMMAND_METHODS - DESTRUCTIVE_COMMAND_METHODS
@@ -38,21 +36,21 @@ module Sycamore
38
36
  # the names of all query methods, which return a boolean
39
37
  PREDICATE_METHODS =
40
38
  %i[nothing? absent? existent? present? blank? empty?
41
- include? include_node? member? key? has_key? include_path? path? >= > < <=
42
- leaf? leaves? internal? external? flat? nested?
43
- sleaf? sleaves? strict_leaf? strict_leaves?
44
- eql? matches? === ==]
39
+ include? include_node? member? key? has_key? include_path? path? >= > < <=
40
+ leaf? leaves? internal? external? flat? nested?
41
+ sleaf? sleaves? strict_leaf? strict_leaves?
42
+ eql? matches? === ==]
45
43
 
46
44
  # the names of all methods, which side-effect-freeze return only a value
47
45
  QUERY_METHODS = PREDICATE_METHODS +
48
46
  %i[new_child dup hash to_native_object to_h to_s inspect
49
- node node! nodes keys child_of child_at dig fetch fetch_path search
50
- size total_size tsize height
51
- each each_path paths each_node each_key each_pair] << :[]
47
+ node node! nodes keys child_of child_at dig fetch fetch_path search
48
+ size total_size tsize height
49
+ each each_path paths each_node each_key each_pair] << :[]
52
50
 
53
51
  %i[COMMAND_METHODS QUERY_METHODS PREDICATE_METHODS
54
- ADDITIVE_COMMAND_METHODS DESTRUCTIVE_COMMAND_METHODS
55
- PURE_ADDITIVE_COMMAND_METHODS PURE_DESTRUCTIVE_COMMAND_METHODS]
52
+ ADDITIVE_COMMAND_METHODS DESTRUCTIVE_COMMAND_METHODS
53
+ PURE_ADDITIVE_COMMAND_METHODS PURE_DESTRUCTIVE_COMMAND_METHODS]
56
54
  .each do |method_set|
57
55
  define_singleton_method(method_set.downcase) { const_get method_set }
58
56
  end
@@ -68,7 +66,7 @@ module Sycamore
68
66
  end
69
67
 
70
68
  protected def data
71
- @data ||= Hash.new
69
+ @data ||= {}
72
70
  end
73
71
 
74
72
  protected def clear_data
@@ -89,13 +87,13 @@ module Sycamore
89
87
  #
90
88
  def self.with(*args)
91
89
  tree = new
92
- tree.add( args.size == 1 ? args.first : args ) unless args.empty?
90
+ tree.add((args.size == 1) ? args.first : args) unless args.empty?
93
91
  tree
94
92
  end
95
93
 
96
94
  class << self
97
- alias from with
98
- alias [] with
95
+ alias_method :from, :with
96
+ alias_method :[], :with
99
97
  end
100
98
 
101
99
  ##
@@ -115,7 +113,6 @@ module Sycamore
115
113
  self.class.new(*args)
116
114
  end
117
115
 
118
-
119
116
  ########################################################################
120
117
  # @group Absence and Nothing predicates
121
118
  ########################################################################
@@ -144,7 +141,7 @@ module Sycamore
144
141
  # @return [Boolean]
145
142
  #
146
143
  def existent?
147
- not absent?
144
+ !absent?
148
145
  end
149
146
 
150
147
  ##
@@ -157,10 +154,9 @@ module Sycamore
157
154
  # @return [Boolean]
158
155
  #
159
156
  def present?
160
- not blank?
157
+ !blank?
161
158
  end
162
159
 
163
-
164
160
  ########################################################################
165
161
  # @group Element access
166
162
  ########################################################################
@@ -208,21 +204,24 @@ module Sycamore
208
204
  # tree.to_h # => {:foo=>{:bar=>[:baz, 1], :qux=>2}}
209
205
  #
210
206
  def add(nodes_or_tree)
211
- case
212
- when nodes_or_tree.equal?(Nothing) then # do nothing
213
- when nodes_or_tree.is_a?(Tree) then add_tree(nodes_or_tree)
214
- when Tree.like?(nodes_or_tree) then add_tree(valid_tree! nodes_or_tree)
215
- when nodes_or_tree.is_a?(Path) then add_path(nodes_or_tree)
216
- when nodes_or_tree.is_a?(Enumerable)
217
- nodes_or_tree.all? { |node| valid_node_element! node }
218
- nodes_or_tree.each { |node| add(node) }
219
- else add_node(nodes_or_tree)
207
+ if nodes_or_tree.equal?(Nothing) # do nothing
208
+ elsif nodes_or_tree.is_a?(Tree)
209
+ add_tree(nodes_or_tree)
210
+ elsif Tree.like?(nodes_or_tree)
211
+ add_tree(valid_tree!(nodes_or_tree))
212
+ elsif nodes_or_tree.is_a?(Path)
213
+ add_path(nodes_or_tree)
214
+ elsif nodes_or_tree.is_a?(Enumerable)
215
+ nodes_or_tree.all? { |node| valid_node_element! node }
216
+ nodes_or_tree.each { |node| add(node) }
217
+ else
218
+ add_node(nodes_or_tree)
220
219
  end
221
220
 
222
221
  self
223
222
  end
224
223
 
225
- alias << add
224
+ alias_method :<<, :add
226
225
 
227
226
  protected def add_node(node)
228
227
  data[node] ||= Nothing
@@ -319,21 +318,23 @@ module Sycamore
319
318
  # tree.to_h # => {foo: :qux}
320
319
  #
321
320
  def delete(nodes_or_tree)
322
- case
323
- when nodes_or_tree.is_a?(Tree) then delete_tree(nodes_or_tree)
324
- when Tree.like?(nodes_or_tree) then delete_tree(valid_tree! nodes_or_tree)
325
- when nodes_or_tree.is_a?(Path) then delete_path(nodes_or_tree)
326
- when nodes_or_tree.is_a?(Enumerable)
327
- nodes_or_tree.all? { |node| valid_node_element! node }
328
- nodes_or_tree.each { |node| delete node }
329
- else
330
- delete_node valid_node!(nodes_or_tree)
321
+ if nodes_or_tree.is_a?(Tree)
322
+ delete_tree(nodes_or_tree)
323
+ elsif Tree.like?(nodes_or_tree)
324
+ delete_tree(valid_tree!(nodes_or_tree))
325
+ elsif nodes_or_tree.is_a?(Path)
326
+ delete_path(nodes_or_tree)
327
+ elsif nodes_or_tree.is_a?(Enumerable)
328
+ nodes_or_tree.all? { |node| valid_node_element! node }
329
+ nodes_or_tree.each { |node| delete node }
330
+ else
331
+ delete_node valid_node!(nodes_or_tree)
331
332
  end
332
333
 
333
334
  self
334
335
  end
335
336
 
336
- alias >> delete
337
+ alias_method :>>, :delete
337
338
 
338
339
  protected def delete_node(node)
339
340
  data.delete(node)
@@ -344,19 +345,19 @@ module Sycamore
344
345
  protected def delete_tree(tree)
345
346
  tree.each do |node_to_delete, child_to_delete|
346
347
  next unless include? node_to_delete
347
- if Nothing.like?(child_to_delete) or
348
- (child_to_delete.respond_to?(:empty?) and child_to_delete.empty?)
348
+ if Nothing.like?(child_to_delete) ||
349
+ (child_to_delete.respond_to?(:empty?) && child_to_delete.empty?)
349
350
  delete_node node_to_delete
350
351
  else
351
352
  fetch(node_to_delete, Nothing).tap do |child|
352
- case
353
- when child.empty? then next
354
- when Tree.like?(child_to_delete)
355
- child.delete_tree(child_to_delete)
356
- when child_to_delete.is_a?(Enumerable)
357
- child_to_delete.each { |node| child.delete_node node }
358
- else
359
- child.delete_node child_to_delete
353
+ if child.empty?
354
+ next
355
+ elsif Tree.like?(child_to_delete)
356
+ child.delete_tree(child_to_delete)
357
+ elsif child_to_delete.is_a?(Enumerable)
358
+ child_to_delete.each { |node| child.delete_node node }
359
+ else
360
+ child.delete_node child_to_delete
360
361
  end
361
362
  delete_node(node_to_delete) if child.empty?
362
363
  end
@@ -368,13 +369,13 @@ module Sycamore
368
369
 
369
370
  protected def delete_path(path)
370
371
  case path.length
371
- when 0 then return self
372
- when 1 then return delete_node(path.node)
372
+ when 0 then return self
373
+ when 1 then return delete_node(path.node)
373
374
  end
374
375
 
375
376
  parent = fetch_path(path.parent) { return self }
376
377
  parent.delete_node(path.node)
377
- delete_path(path.parent) if parent.empty? and not path.parent.root?
378
+ delete_path(path.parent) if parent.empty? && !path.parent.root?
378
379
 
379
380
  self
380
381
  end
@@ -472,7 +473,7 @@ module Sycamore
472
473
  #
473
474
  def []=(*args)
474
475
  path, nodes_or_tree = args[0..-2], args[-1]
475
- raise ArgumentError, 'wrong number of arguments (given 1, expected 2)' if path.empty?
476
+ raise ArgumentError, "wrong number of arguments (given 1, expected 2)" if path.empty?
476
477
 
477
478
  if Nothing.like? nodes_or_tree
478
479
  if path.size == 1
@@ -516,17 +517,19 @@ module Sycamore
516
517
  # tree.to_h # => {foo: :bar}
517
518
  #
518
519
  def compact
519
- data.each do |node, child| case
520
- when child.nothing? then next
521
- when child.empty? then clear_child_of_node(node)
522
- else child.compact
520
+ data.each do |node, child|
521
+ if child.nothing?
522
+ next
523
+ elsif child.empty?
524
+ clear_child_of_node(node)
525
+ else
526
+ child.compact
523
527
  end
524
528
  end
525
529
 
526
530
  self
527
531
  end
528
532
 
529
-
530
533
  #####################
531
534
  # query methods #
532
535
  #####################
@@ -545,8 +548,7 @@ module Sycamore
545
548
  data.keys
546
549
  end
547
550
 
548
- alias keys nodes # Hash compatibility
549
-
551
+ alias_method :keys, :nodes # Hash compatibility
550
552
 
551
553
  ##
552
554
  # The only node of this tree or an exception, if more {#nodes nodes} present.
@@ -587,7 +589,7 @@ module Sycamore
587
589
  # @see Tree#node
588
590
  #
589
591
  def node!
590
- raise EmptyNodeSet, 'no node present' if empty?
592
+ raise EmptyNodeSet, "no node present" if empty?
591
593
  node
592
594
  end
593
595
 
@@ -640,21 +642,21 @@ module Sycamore
640
642
  def child_at(*path)
641
643
  first = path.first
642
644
  case path.length
643
- when 0
644
- raise ArgumentError, 'wrong number of arguments (given 0, expected 1+)'
645
- when 1
646
- if first.is_a? Enumerable
647
- child_at(*first)
648
- else
649
- child_of(*path)
650
- end
645
+ when 0
646
+ raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
647
+ when 1
648
+ if first.is_a? Enumerable
649
+ child_at(*first)
651
650
  else
652
- child_of(first).child_at(*path[1..-1])
651
+ child_of(*path)
652
+ end
653
+ else
654
+ child_of(first).child_at(*path[1..])
653
655
  end
654
656
  end
655
657
 
656
- alias [] child_at
657
- alias dig child_at # Hash compatibility
658
+ alias_method :[], :child_at
659
+ alias_method :dig, :child_at # Hash compatibility
658
660
 
659
661
  ##
660
662
  # The child tree of a node.
@@ -693,10 +695,12 @@ module Sycamore
693
695
 
694
696
  child = data.fetch(node, *default, &block)
695
697
  if child.equal? Nothing
696
- child = case
697
- when block_given? then yield
698
- when !default.empty? then default.first
699
- else raise ChildError, "node #{node.inspect} has no child tree"
698
+ child = if block
699
+ yield
700
+ elsif !default.empty?
701
+ default.first
702
+ else
703
+ raise ChildError, "node #{node.inspect} has no child tree"
700
704
  end
701
705
  end
702
706
 
@@ -727,10 +731,10 @@ module Sycamore
727
731
  # tree.fetch_path([:foo, :bar, :baz], :default) # => :default
728
732
  #
729
733
  def fetch_path(path, *default, &block)
730
- default_case = block_given? || !default.empty?
734
+ default_case = block || !default.empty?
731
735
  path.inject(self) do |tree, node|
732
736
  if default_case
733
- tree.fetch(node) { return block_given? ? yield : default.first }
737
+ tree.fetch(node) { return block ? yield : default.first }
734
738
  else
735
739
  tree.fetch(node)
736
740
  end
@@ -759,14 +763,14 @@ module Sycamore
759
763
  # > b
760
764
  #
761
765
  def each_node(&block)
762
- return enum_for(__callee__) unless block_given?
766
+ return enum_for(__callee__) unless block
763
767
 
764
768
  data.each_key(&block)
765
769
 
766
770
  self
767
771
  end
768
772
 
769
- alias each_key each_node # Hash compatibility
773
+ alias_method :each_key, :each_node # Hash compatibility
770
774
 
771
775
  ##
772
776
  # Iterates over all {#nodes nodes} and their child trees.
@@ -788,14 +792,14 @@ module Sycamore
788
792
  # > b => #<Tree: Nothing>
789
793
  #
790
794
  def each_pair(&block)
791
- return enum_for(__callee__) unless block_given?
795
+ return enum_for(__callee__) unless block
792
796
 
793
797
  data.each_pair(&block)
794
798
 
795
799
  self
796
800
  end
797
801
 
798
- alias each each_pair
802
+ alias_method :each, :each_pair
799
803
 
800
804
  ##
801
805
  # Iterates over the {Path paths} to all leaves of this tree.
@@ -818,7 +822,7 @@ module Sycamore
818
822
  # > #<Path: /b/foo/baz>
819
823
  #
820
824
  def each_path(with_ancestor: Path::ROOT, &block)
821
- return enum_for(__callee__) unless block_given?
825
+ return enum_for(__callee__) unless block
822
826
 
823
827
  each do |node, child|
824
828
  if child.empty?
@@ -831,7 +835,7 @@ module Sycamore
831
835
  self
832
836
  end
833
837
 
834
- alias paths each_path
838
+ alias_method :paths, :each_path
835
839
 
836
840
  ##
837
841
  # Checks if a path of nodes exists in this tree.
@@ -848,9 +852,9 @@ module Sycamore
848
852
  #
849
853
  def include_path?(*args)
850
854
  case args.count
851
- when 0 then raise ArgumentError, 'wrong number of arguments (given 0, expected 1+)'
852
- when 1 then path = args.first
853
- else return include_path?(args)
855
+ when 0 then raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
856
+ when 1 then path = args.first
857
+ else return include_path?(args)
854
858
  end
855
859
  path = [path] unless path.is_a? Enumerable
856
860
 
@@ -861,7 +865,7 @@ module Sycamore
861
865
  end
862
866
  end
863
867
 
864
- alias path? include_path?
868
+ alias_method :path?, :include_path?
865
869
 
866
870
  ##
867
871
  # Checks if a node exists in the {#nodes nodes} set of this tree.
@@ -880,9 +884,9 @@ module Sycamore
880
884
  data.include?(node)
881
885
  end
882
886
 
883
- alias member? include_node? # Hash compatibility
884
- alias has_key? include_node? # Hash compatibility
885
- alias key? include_node? # Hash compatibility
887
+ alias_method :member?, :include_node? # Hash compatibility
888
+ alias_method :has_key?, :include_node? # Hash compatibility
889
+ alias_method :key?, :include_node? # Hash compatibility
886
890
 
887
891
  ##
888
892
  # Checks if some nodes or a full tree-like structure is included in this tree.
@@ -899,24 +903,23 @@ module Sycamore
899
903
  # tree.include?("a", "b" => 200) # => true
900
904
  #
901
905
  def include?(*elements)
902
- raise ArgumentError, 'wrong number of arguments (given 0, expected 1+)' if
906
+ raise ArgumentError, "wrong number of arguments (given 0, expected 1+)" if
903
907
  elements.size == 0
904
908
  return elements.all? { |element| include? element } if
905
909
  elements.size > 1
906
910
 
907
911
  elements = elements.first
908
- case
909
- when Tree.like?(elements)
910
- elements.all? do |node, child|
911
- include_node?(node) and ( child.nil? or child.equal?(Nothing) or
912
- self.child_of(node).include?(child) )
913
- end
914
- when elements.is_a?(Path)
915
- include_path? elements
916
- when elements.is_a?(Enumerable)
917
- elements.all? { |element| include_node? element }
918
- else
919
- include_node? elements
912
+ if Tree.like?(elements)
913
+ elements.all? do |node, child|
914
+ include_node?(node) and (child.nil? or child.equal?(Nothing) or
915
+ child_of(node).include?(child))
916
+ end
917
+ elsif elements.is_a?(Path)
918
+ include_path? elements
919
+ elsif elements.is_a?(Enumerable)
920
+ elements.all? { |element| include_node? element }
921
+ else
922
+ include_node? elements
920
923
  end
921
924
  end
922
925
 
@@ -941,7 +944,7 @@ module Sycamore
941
944
  protected def _search(query, current_path: Path::ROOT, results: [])
942
945
  results << current_path if include?(query)
943
946
  each do |node, child|
944
- child._search(query, current_path: current_path/node, results: results)
947
+ child._search(query, current_path: current_path / node, results: results)
945
948
  end
946
949
  results
947
950
  end
@@ -982,7 +985,7 @@ module Sycamore
982
985
  total
983
986
  end
984
987
 
985
- alias tsize total_size
988
+ alias_method :tsize, :total_size
986
989
 
987
990
  ##
988
991
  # The length of the longest path of this tree.
@@ -1011,7 +1014,7 @@ module Sycamore
1011
1014
  data.empty?
1012
1015
  end
1013
1016
 
1014
- alias blank? empty?
1017
+ alias_method :blank?, :empty?
1015
1018
 
1016
1019
  ##
1017
1020
  # Checks if the given node has no children.
@@ -1047,7 +1050,7 @@ module Sycamore
1047
1050
  include_node?(node) && child_at(node).absent?
1048
1051
  end
1049
1052
 
1050
- alias sleaf? strict_leaf?
1053
+ alias_method :sleaf?, :strict_leaf?
1051
1054
 
1052
1055
  ##
1053
1056
  # Checks if all given nodes or that of the tree have no children, even not an empty child tree.
@@ -1076,7 +1079,7 @@ module Sycamore
1076
1079
  nodes.all? { |node| strict_leaf?(node) }
1077
1080
  end
1078
1081
 
1079
- alias sleaves? strict_leaves?
1082
+ alias_method :sleaves?, :strict_leaves?
1080
1083
 
1081
1084
  ##
1082
1085
  # Checks if all given nodes or that of the tree have no children.
@@ -1105,8 +1108,8 @@ module Sycamore
1105
1108
  nodes.all? { |node| leaf?(node) }
1106
1109
  end
1107
1110
 
1108
- alias leaves? external?
1109
- alias flat? external?
1111
+ alias_method :leaves?, :external?
1112
+ alias_method :flat?, :external?
1110
1113
 
1111
1114
  ##
1112
1115
  # Checks if all given nodes or that of the tree have children.
@@ -1134,14 +1137,13 @@ module Sycamore
1134
1137
  # One would expect it to be the negation of #external? without arguments.
1135
1138
  #
1136
1139
  def internal?(*nodes)
1137
- return false if self.empty?
1140
+ return false if empty?
1138
1141
  nodes = self.nodes if nodes.empty?
1139
1142
 
1140
- nodes.all? { |node| not leaf?(node) and include_node?(node) }
1143
+ nodes.all? { |node| !leaf?(node) and include_node?(node) }
1141
1144
  end
1142
1145
 
1143
- alias nested? internal?
1144
-
1146
+ alias_method :nested?, :internal?
1145
1147
 
1146
1148
  ########################################################################
1147
1149
  # @group Comparison
@@ -1246,7 +1248,7 @@ module Sycamore
1246
1248
  # tree1 >= tree1 # => true
1247
1249
  #
1248
1250
  def >=(other)
1249
- (other.is_a?(Tree) or other.is_a?(Absence)) and self.include?(other)
1251
+ (other.is_a?(Tree) or other.is_a?(Absence)) and include?(other)
1250
1252
  end
1251
1253
 
1252
1254
  ##
@@ -1263,7 +1265,7 @@ module Sycamore
1263
1265
  # tree1 > tree1 # => false
1264
1266
  #
1265
1267
  def >(other)
1266
- (other.is_a?(Tree) or other.is_a?(Absence)) and self.include?(other) and self != other
1268
+ (other.is_a?(Tree) or other.is_a?(Absence)) and include?(other) and self != other
1267
1269
  end
1268
1270
 
1269
1271
  ##
@@ -1281,17 +1283,19 @@ module Sycamore
1281
1283
  # Problem: Requires a solution which doesn't use +Hash#include?+.
1282
1284
  #
1283
1285
  def matches?(other)
1284
- case
1285
- when Tree.like?(other) then matches_tree?(other)
1286
- when other.is_a?(Enumerable) then matches_enumerable?(other)
1287
- else matches_atom?(other)
1286
+ if Tree.like?(other)
1287
+ matches_tree?(other)
1288
+ elsif other.is_a?(Enumerable)
1289
+ matches_enumerable?(other)
1290
+ else
1291
+ matches_atom?(other)
1288
1292
  end
1289
1293
  end
1290
1294
 
1291
- alias === matches?
1295
+ alias_method :===, :matches?
1292
1296
 
1293
1297
  private def matches_atom?(other)
1294
- not other.nil? and (size == 1 and nodes.first == other and leaf? other)
1298
+ !other.nil? and (size == 1 and nodes.first == other and leaf? other)
1295
1299
  end
1296
1300
 
1297
1301
  private def matches_enumerable?(other)
@@ -1304,15 +1308,15 @@ module Sycamore
1304
1308
  all? { |node, child|
1305
1309
  if child.nothing?
1306
1310
  other.include?(node) and begin other_child = other.fetch(node, nil)
1307
- not other_child or
1308
- (other_child.respond_to?(:empty?) and other_child.empty?)
1311
+ !other_child or
1312
+ (other_child.respond_to?(:empty?) and other_child.empty?)
1309
1313
  end
1310
1314
  else
1311
1315
  child.matches? other[node]
1312
- end }
1316
+ end
1317
+ }
1313
1318
  end
1314
1319
 
1315
-
1316
1320
  ########################################################################
1317
1321
  # @group Conversion
1318
1322
  ########################################################################
@@ -1325,13 +1329,12 @@ module Sycamore
1325
1329
  # @api private
1326
1330
  #
1327
1331
  def to_native_object(sleaf_child_as: nil, special_nil: false)
1328
- case
1329
- when empty?
1330
- []
1331
- when strict_leaves?
1332
- size == 1 && (!special_nil || !nodes.first.nil?) ? nodes.first : nodes
1333
- else
1334
- to_h(sleaf_child_as: sleaf_child_as, special_nil: special_nil)
1332
+ if empty?
1333
+ []
1334
+ elsif strict_leaves?
1335
+ (size == 1 && (!special_nil || !nodes.first.nil?)) ? nodes.first : nodes
1336
+ else
1337
+ to_h(sleaf_child_as: sleaf_child_as, special_nil: special_nil)
1335
1338
  end
1336
1339
  end
1337
1340
 
@@ -1392,12 +1395,11 @@ module Sycamore
1392
1395
  #
1393
1396
  private def valid_node_element!(node)
1394
1397
  raise InvalidNode, "#{node} is not a valid tree node" if
1395
- node.is_a?(Enumerable) and not node.is_a?(Path) and not Tree.like?(node)
1398
+ node.is_a?(Enumerable) && !node.is_a?(Path) && !Tree.like?(node)
1396
1399
 
1397
1400
  node
1398
1401
  end
1399
1402
 
1400
-
1401
1403
  # @api private
1402
1404
  #
1403
1405
  private def valid_node!(node)
@@ -1420,15 +1422,15 @@ module Sycamore
1420
1422
  #
1421
1423
  def self.tree_like?(object)
1422
1424
  case object
1423
- when Hash, Tree, Absence # ... ?!
1424
- true
1425
- else
1426
- (object.respond_to? :tree_like? and object.tree_like?) # or ...
1425
+ when Hash, Tree, Absence # ... ?!
1426
+ true
1427
+ else
1428
+ (object.respond_to? :tree_like? and object.tree_like?) # or ...
1427
1429
  end
1428
1430
  end
1429
1431
 
1430
1432
  class << self
1431
- alias like? tree_like?
1433
+ alias_method :like?, :tree_like?
1432
1434
  end
1433
1435
 
1434
1436
  ########################################################################
@@ -1441,8 +1443,7 @@ module Sycamore
1441
1443
  # @return [Tree]
1442
1444
  #
1443
1445
  def dup
1444
- duplicate = self.class.new.add(self)
1445
- duplicate
1446
+ self.class.new.add(self)
1446
1447
  end
1447
1448
 
1448
1449
  ##
@@ -1464,6 +1465,5 @@ module Sycamore
1464
1465
  each { |_, child| child.freeze }
1465
1466
  super
1466
1467
  end
1467
-
1468
1468
  end # Tree
1469
1469
  end # Sycamore
@@ -2,27 +2,33 @@ module Sycamore
2
2
  # version representation
3
3
  module VERSION
4
4
  # the file containing the project version number
5
- FILE = File.expand_path('../../../VERSION', __FILE__)
6
- MAJOR, MINOR, TINY, EXTRA = File.read(FILE).chomp.split('.')
5
+ FILE = File.expand_path("../../../VERSION", __FILE__)
6
+ MAJOR, MINOR, TINY, EXTRA = File.read(FILE).chomp.split(".")
7
7
  # the normalized version string
8
- STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.').freeze
8
+ STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join(".").freeze
9
9
 
10
10
  ##
11
11
  # @return [String]
12
- def self.to_s() STRING end
12
+ def self.to_s
13
+ STRING
14
+ end
13
15
 
14
16
  ##
15
17
  # @return [String]
16
- def self.to_str() STRING end
18
+ def self.to_str
19
+ STRING
20
+ end
17
21
 
18
22
  ##
19
23
  # @return [Array(Integer, Integer, Integer)]
20
- def self.to_a() [MAJOR, MINOR, TINY] end
24
+ def self.to_a
25
+ [MAJOR, MINOR, TINY]
26
+ end
21
27
 
22
28
  ##
23
29
  # @return [Boolean]
24
30
  def self.==(other)
25
- other == self.to_s
31
+ other == to_s
26
32
  end
27
33
  end
28
34
  end
data/lib/sycamore.rb CHANGED
@@ -1,10 +1,10 @@
1
- require 'sycamore/version'
2
- require 'sycamore/exceptions'
3
- require 'sycamore/path'
4
- require 'sycamore/path_root'
5
- require 'sycamore/tree'
6
- require 'sycamore/nothing'
7
- require 'sycamore/absence'
1
+ require "sycamore/version"
2
+ require "sycamore/exceptions"
3
+ require "sycamore/path"
4
+ require "sycamore/path_root"
5
+ require "sycamore/tree"
6
+ require "sycamore/nothing"
7
+ require "sycamore/absence"
8
8
 
9
9
  ##
10
10
  # see README.md
@@ -1,2 +1,2 @@
1
- $LOAD_PATH << 'lib'
2
- require 'sycamore/extension'
1
+ $LOAD_PATH << "lib"
2
+ require "sycamore/extension"
data/sycamore.gemspec CHANGED
@@ -1,29 +1,28 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path("../lib", __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'sycamore/version'
3
+ require "sycamore/version"
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = 'metaractor-sycamore'
8
- spec.version = Sycamore::VERSION
9
- spec.authors = ['Marcel Otto', 'Ryan Schlesinger']
10
- spec.email = ['ryan@ryanschlesinger.com']
6
+ spec.name = "metaractor-sycamore"
7
+ spec.version = Sycamore::VERSION
8
+ spec.authors = ["Marcel Otto", "Ryan Schlesinger"]
9
+ spec.email = ["ryan@ryanschlesinger.com"]
11
10
 
12
- spec.summary = %q{An unordered tree data structure for Ruby.}
13
- spec.description = %q{Sycamore is an unordered tree data structure.}
14
- spec.homepage = 'https://github.com/metaractor/sycamore'
15
- spec.license = 'MIT'
11
+ spec.summary = "An unordered tree data structure for Ruby."
12
+ spec.description = "Sycamore is an unordered tree data structure."
13
+ spec.homepage = "https://github.com/metaractor/sycamore"
14
+ spec.license = "MIT"
16
15
 
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = 'exe'
19
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ['lib']
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
21
20
 
22
- spec.required_ruby_version = '>= 2.7'
21
+ spec.required_ruby_version = ">= 2.7"
23
22
 
24
- spec.add_development_dependency 'bundler', '~> 2'
25
- spec.add_development_dependency 'rake', '~> 13.0'
26
- spec.add_development_dependency 'rspec', '~> 3.11'
27
- spec.add_development_dependency 'yard', '~> 0.9'
28
- spec.add_development_dependency 'yard-doctest', '0.1.7'
23
+ spec.add_development_dependency "bundler", "~> 2"
24
+ spec.add_development_dependency "rake", "~> 13.0"
25
+ spec.add_development_dependency "rspec", "~> 3.11"
26
+ spec.add_development_dependency "yard", "~> 0.9"
27
+ spec.add_development_dependency "yard-doctest", "0.1.7"
29
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metaractor-sycamore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcel Otto