metaractor-sycamore 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -4
- data/Rakefile +13 -14
- data/VERSION +1 -1
- data/lib/sycamore/absence.rb +9 -12
- data/lib/sycamore/exceptions.rb +5 -5
- data/lib/sycamore/extension/nothing.rb +1 -1
- data/lib/sycamore/extension/path.rb +1 -1
- data/lib/sycamore/extension/tree.rb +1 -1
- data/lib/sycamore/extension.rb +2 -2
- data/lib/sycamore/nothing.rb +5 -10
- data/lib/sycamore/path.rb +25 -27
- data/lib/sycamore/path_root.rb +5 -5
- data/lib/sycamore/stree.rb +1 -1
- data/lib/sycamore/tree.rb +146 -146
- data/lib/sycamore/version.rb +13 -7
- data/lib/sycamore.rb +7 -7
- data/support/doctest_helper.rb +2 -2
- data/sycamore.gemspec +20 -21
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae5565f1e3e26149ac616264c7f80814ec43d0402af467d3bd39a0a95a242007
|
4
|
+
data.tar.gz: 6ac8b42b9cbfd6b1c2bbb32bb5415ca0f099d40c3cced190e264297f215414ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31278db416f78913b21d63f384b5a02e195d3d47ceb6a91a847fd0489b99c7164bfc7c0629e046eabe8ee629a3de7006c684da9fd8f7e32e3cdfd86b3bb4169a
|
7
|
+
data.tar.gz: 1e2e022767207c83f0fd3da132a11e67f9dcc866140ac3751e1624b737a994a0c2e87856363b95ae0d84033b531f35a6d86533537f86df58822abf89714ce223
|
data/Gemfile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
group :debug do
|
6
|
-
gem
|
7
|
-
gem
|
6
|
+
gem "guard-rspec"
|
7
|
+
gem "pry"
|
8
8
|
end
|
9
9
|
|
10
10
|
group :test do
|
11
|
-
gem
|
11
|
+
gem "coveralls", require: false, platform: :mri
|
12
12
|
end
|
data/Rakefile
CHANGED
@@ -1,36 +1,35 @@
|
|
1
|
-
require
|
1
|
+
require "bundler/gem_tasks"
|
2
2
|
|
3
3
|
begin
|
4
|
-
require
|
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
|
11
|
+
require "yard"
|
12
12
|
YARD::Rake::YardocTask.new do |t|
|
13
|
-
t.options = [
|
14
|
-
t.files
|
15
|
-
t.stats_options = [
|
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
|
22
|
+
require "yard-doctest"
|
23
23
|
YARD::Doctest::RakeTask.new do |task|
|
24
24
|
task.doctest_opts = %w[]
|
25
|
-
task.pattern =
|
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 :
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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.
|
1
|
+
0.4.3
|
data/lib/sycamore/absence.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require
|
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
|
-
|
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
|
-
|
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
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
109
|
-
|
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? ?
|
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
|
data/lib/sycamore/exceptions.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
module Sycamore
|
2
2
|
# raised when a value is not a valid node
|
3
|
-
class InvalidNode < ArgumentError
|
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
|
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
|
9
|
+
class NonUniqueNodeSet < StandardError; end
|
10
10
|
|
11
11
|
# raised when calling {Tree#node!} on a Tree without nodes
|
12
|
-
class EmptyNodeSet < StandardError
|
12
|
+
class EmptyNodeSet < StandardError; end
|
13
13
|
|
14
14
|
# raised when trying to fetch the child of a leaf
|
15
|
-
class ChildError < KeyError
|
15
|
+
class ChildError < KeyError; end
|
16
16
|
end
|
data/lib/sycamore/extension.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "sycamore/extension/tree"
|
2
|
+
require "sycamore/extension/nothing"
|
data/lib/sycamore/nothing.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require
|
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,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
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
|
-
|
112
|
-
|
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
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
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
|
-
|
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
|
-
|
218
|
-
i = other.each
|
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
|
228
|
-
i = other.each
|
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
|
data/lib/sycamore/path_root.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
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
|
-
|
33
|
+
"#<Path:Root>"
|
34
34
|
end
|
35
35
|
|
36
36
|
def inspect
|
37
|
-
|
37
|
+
"#<Sycamore::Path::Root>"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
data/lib/sycamore/stree.rb
CHANGED
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
|
-
|
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
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
55
|
-
|
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 ||=
|
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(
|
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
|
-
|
98
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
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
|
-
|
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
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
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
|
-
|
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)
|
348
|
-
(child_to_delete.respond_to?(: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
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
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
|
-
|
372
|
-
|
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?
|
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,
|
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|
|
520
|
-
|
521
|
-
|
522
|
-
|
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
|
-
|
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,
|
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
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
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(
|
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
|
-
|
657
|
-
|
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 =
|
697
|
-
|
698
|
-
|
699
|
-
|
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 =
|
734
|
+
default_case = block || !default.empty?
|
731
735
|
path.inject(self) do |tree, node|
|
732
736
|
if default_case
|
733
|
-
tree.fetch(node) { return
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
852
|
-
|
853
|
-
|
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
|
-
|
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
|
-
|
884
|
-
|
885
|
-
|
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,
|
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
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1109
|
-
|
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
|
1140
|
+
return false if empty?
|
1138
1141
|
nodes = self.nodes if nodes.empty?
|
1139
1142
|
|
1140
|
-
nodes.all? { |node|
|
1143
|
+
nodes.all? { |node| !leaf?(node) and include_node?(node) }
|
1141
1144
|
end
|
1142
1145
|
|
1143
|
-
|
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
|
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
|
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
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
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
|
-
|
1295
|
+
alias_method :===, :matches?
|
1292
1296
|
|
1293
1297
|
private def matches_atom?(other)
|
1294
|
-
|
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
|
-
|
1308
|
-
|
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
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
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)
|
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
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/sycamore/version.rb
CHANGED
@@ -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(
|
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(
|
8
|
+
STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join(".").freeze
|
9
9
|
|
10
10
|
##
|
11
11
|
# @return [String]
|
12
|
-
def self.to_s
|
12
|
+
def self.to_s
|
13
|
+
STRING
|
14
|
+
end
|
13
15
|
|
14
16
|
##
|
15
17
|
# @return [String]
|
16
|
-
def self.to_str
|
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
|
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 ==
|
31
|
+
other == to_s
|
26
32
|
end
|
27
33
|
end
|
28
34
|
end
|
data/lib/sycamore.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
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
|
data/support/doctest_helper.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
$LOAD_PATH <<
|
2
|
-
require
|
1
|
+
$LOAD_PATH << "lib"
|
2
|
+
require "sycamore/extension"
|
data/sycamore.gemspec
CHANGED
@@ -1,29 +1,28 @@
|
|
1
|
-
|
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
|
3
|
+
require "sycamore/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
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
|
13
|
-
spec.description
|
14
|
-
spec.homepage
|
15
|
-
spec.license
|
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
|
18
|
-
spec.bindir
|
19
|
-
spec.executables
|
20
|
-
spec.require_paths = [
|
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 =
|
21
|
+
spec.required_ruby_version = ">= 2.7"
|
23
22
|
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
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
|