rooted_tree 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a23c9e6f541bfd82e32fa1417fefd88b8357e843
4
+ data.tar.gz: 05ac69ac576ba55e81c05d064d1adaa73380a8e6
5
+ SHA512:
6
+ metadata.gz: dcffedd7ac50e2220bdd1dd7e6dbc9158bda7144eaa79c60e5a3c39a15375e1e7a7b3e6b77a7d316d48c5c4b8115444e732f6f6659a7b6a304770e12596fc452
7
+ data.tar.gz: e76035b943dabc64f8455d158f6d0074cbbb3605eb253646045e9538fba115c7321d961c7936e86e2d4bc48b4e6f51ef72d834aae2c332ffd82a22e7e181051f
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rooted_tree.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Sebastian Lindberg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # RootedTree
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/richtext.png)](http://badge.fury.io/rb/rooted_tree)
4
+ [![Build Status](https://travis-ci.org/seblindberg/ruby-rooted_tree.svg?branch=master)](https://travis-ci.org/seblindberg/ruby-rooted_tree)
5
+ [![Coverage Status](https://coveralls.io/repos/github/seblindberg/ruby-rooted_tree/badge.svg?branch=master)](https://coveralls.io/github/seblindberg/ruby-rooted_tree?branch=master)
6
+
7
+ A tree is a connected graph with no cycles. There, that is plenty of explanation. Please refer to https://en.wikipedia.org/wiki/Tree_structure for a more in depth description, but if you need one this library probably is not for you.
8
+
9
+ This gem technically implements a _rooted, ordered tree_, but that name is a mouthful. It is ment to be used as a building block when working with any tree shaped data. For a brief recap of the terminology please see below.
10
+
11
+ A A is the root.
12
+ ┌────┼──┐ B, C and D are all children of A.
13
+ B C D E is a descendant of A.
14
+ ┌─┼─┐ ┌┴┐ │ A is of degree 3 while C is of degree 2.
15
+ E F G H I J F is a leaf.
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'rooted_tree'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install rooted_tree
32
+
33
+ ## Usage
34
+
35
+ Please see the documentation for the complete API.
36
+
37
+ ```ruby
38
+ # Create some nodes
39
+ root = RootedTree::Node.new
40
+ child_a = RootedTree::Node.new
41
+ child_b = RootedTree::Node.new
42
+
43
+ # Put the two children below the root
44
+ root << child_a << child_b
45
+
46
+ # Look at the result
47
+ p root # => RootedTree::Node:0x3fd5d54efda0
48
+ # ├─╴RootedTree::Node:0x3fd5d54c3ea8
49
+ # └─╴RootedTree::Node:0x3fd5d54ba894
50
+ ```
51
+
52
+ The gem is primarily ment to be extended by other classes. The following example builds a tree of the files in the file system and displays it much like the command line tool `tree`.
53
+
54
+ ```ruby
55
+ class FileSystemItem < RootedTree::Node
56
+ attr_reader :name
57
+
58
+ def initialize name
59
+ super()
60
+ @name = name
61
+ end
62
+
63
+ def display
64
+ inspect { |item| item.name }
65
+ end
66
+
67
+ def self.map_to_path path = '.', root: new(path)
68
+ # Iterate over all of the files in the directory
69
+ Dir[path + '/*'].each do |entry|
70
+ # Create a new FileSystemItem for the entry
71
+ item = new File.basename entry
72
+ root << item
73
+ # Continue to map the files and directories under
74
+ # entry, if it is a directory
75
+ map_to_path entry, root: item unless File.file? entry
76
+ end
77
+
78
+ root
79
+ end
80
+ end
81
+
82
+ puts FileSystemItem.map_to_path('.').display
83
+ ```
84
+
85
+ ## Development
86
+
87
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
88
+
89
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
90
+
91
+ ## Contributing
92
+
93
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rooted_tree.
94
+
95
+
96
+ ## License
97
+
98
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
99
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rooted_tree"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rooted_tree'
4
+
5
+ # FileSystemItem
6
+ #
7
+ # Maps the entries in the file system to `Node` objects via .map_to_path. The
8
+ # Node#inspect method is then exploited in #display to show the resulting tree
9
+ # structure.
10
+
11
+ class FileSystemItem < RootedTree::Node
12
+ attr_reader :name
13
+
14
+ def initialize name
15
+ super()
16
+ @name = name
17
+ end
18
+
19
+ def display
20
+ inspect { |item| item.name }
21
+ end
22
+
23
+ def self.map_to_path path = '.', root: new(path)
24
+ # Iterate over all of the files in the directory
25
+ Dir[path + '/*'].each do |entry|
26
+ # Create a new FileSystemItem for the entry
27
+ item = new File.basename entry
28
+ root << item
29
+ # Continue to map the files and directories under
30
+ # entry, if it is a directory
31
+ map_to_path entry, root: item unless File.file? entry
32
+ end
33
+
34
+ root
35
+ end
36
+ end
37
+
38
+ puts FileSystemItem.map_to_path('.').display
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rooted_tree/version'
4
+ require 'rooted_tree/node'
5
+ require 'rooted_tree/tree'
6
+
7
+ module RootedTree
8
+ class StructureException < StandardError; end
9
+ end
@@ -0,0 +1,413 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Node
4
+ #
5
+ #
6
+ # The following is an example of a rooted tree of height 3.
7
+ #
8
+ # r - r, a, b, c, and d are internal vertices
9
+ # +--+---+ - vertices e, f, g, h, i, and j are leaves
10
+ # a b c - vertices g, h, and i are siblings
11
+ # +++ | +-+-+ - node a is an ancestor of j
12
+ # d e f g h i - j is a descendant of a
13
+ # |
14
+ # j
15
+ #
16
+ # The terminology is mostly referenced from
17
+ # http://www.cs.columbia.edu/~cs4203/files/GT-Lec4.pdf.
18
+
19
+ module RootedTree
20
+ class Node
21
+ attr_accessor :first_child, :last_child
22
+ attr_writer :next, :prev, :parent
23
+ protected :next=, :prev=, :parent=, :first_child=, :last_child=
24
+
25
+ def initialize
26
+ @parent = nil
27
+ @next = nil
28
+ @prev = nil
29
+ @first_child = nil
30
+ @last_child = nil
31
+ end
32
+
33
+ def initialize_copy(*)
34
+ duped_children = children.map { |v| v.dup.tap { |w| w.parent = self } }
35
+ duped_children.each_cons(2) { |a, b| a.next, b.prev = b, a }
36
+
37
+ @parent = nil
38
+ @first_child = duped_children.first
39
+ @last_child = duped_children.last
40
+ end
41
+
42
+ # Leaf?
43
+ #
44
+ # A node is a leaf if it has no children.
45
+
46
+ def leaf?
47
+ @first_child.nil?
48
+ end
49
+
50
+ # Internal?
51
+ #
52
+ # Returns true if the node is internal, which is equivalent to it having
53
+ # children.
54
+
55
+ def internal?
56
+ !leaf?
57
+ end
58
+
59
+ # Root?
60
+ #
61
+ # Returns true if node has no parent.
62
+
63
+ def root?
64
+ @parent.nil?
65
+ end
66
+
67
+ # Root
68
+ #
69
+ # Returns the root of the tree.
70
+
71
+ def root
72
+ return self if root?
73
+
74
+ node = self
75
+ loop { node = node.parent }
76
+ node
77
+ end
78
+
79
+ # First?
80
+ #
81
+ # Returns true if this node is the first of its siblings.
82
+
83
+ def first?
84
+ @prev.nil?
85
+ end
86
+
87
+ # Last?
88
+ #
89
+ # Returns true if this node is the last of its siblings.
90
+
91
+ def last?
92
+ @next.nil?
93
+ end
94
+
95
+ # Depth
96
+ #
97
+ # Returns the depth of the node within the tree
98
+
99
+ def depth
100
+ ancestors.count
101
+ end
102
+
103
+ alias level depth
104
+
105
+ # Degree
106
+ #
107
+ # Returns the number of children of the node.
108
+
109
+ def degree
110
+ children.count
111
+ end
112
+
113
+ alias arity degree
114
+
115
+ # Size
116
+ #
117
+ # Calculate the size in vertecies of the subtree.
118
+
119
+ def size
120
+ children.reduce(1) { |a, e| a + e.size }
121
+ end
122
+
123
+ # Next
124
+ #
125
+ # Access the next sibling. Raises a StopIteration if this node is the last
126
+ # one.
127
+
128
+ def next
129
+ raise StopIteration if last?
130
+ @next
131
+ end
132
+
133
+ # Prev(ious)
134
+ #
135
+ # Access the previous sibling. Raises a StopIteration if this node is the
136
+ # first one.
137
+
138
+ def prev
139
+ raise StopIteration if first?
140
+ @prev
141
+ end
142
+
143
+ alias previous prev
144
+
145
+ # Parent
146
+ #
147
+ # Access the parent node. Raises a StopIteration if this node is the
148
+ # root.
149
+
150
+ def parent
151
+ raise StopIteration if root?
152
+ @parent
153
+ end
154
+
155
+ # Append Sibling
156
+ #
157
+ # Insert a child between this node and the one after it.
158
+
159
+ def append_sibling(node)
160
+ raise StructureException, 'Root node can not have siblings' if root?
161
+
162
+ node.next = @next
163
+ node.prev = self
164
+ node.parent = @parent
165
+ if @next
166
+ @next.prev = node
167
+ else
168
+ @parent.last_child = node
169
+ end
170
+ @next = node
171
+ end
172
+
173
+ # Prepend Sibling
174
+ #
175
+ # Insert a child between this node and the one before it.
176
+
177
+ def prepend_sibling(node)
178
+ raise StructureException, 'Root node can not have siblings' if root?
179
+
180
+ node.next = self
181
+ node.prev = @prev
182
+ node.parent = @parent
183
+ if @prev
184
+ @prev.next = node
185
+ else
186
+ @parent.first_child = node
187
+ end
188
+ @prev = node
189
+ end
190
+
191
+ # Append Child
192
+ #
193
+ # Insert a child after the last one.
194
+
195
+ def append_child(child)
196
+ if leaf?
197
+ @first_child = @last_child = child
198
+ child.next = child.prev = nil
199
+ child.parent = self
200
+ else
201
+ @last_child.append_sibling child
202
+ end
203
+ self
204
+ end
205
+
206
+ # Prepend Child
207
+ #
208
+ # Insert a child before the first one.
209
+
210
+ def prepend_child(child)
211
+ if leaf?
212
+ @first_child = @last_child = child
213
+ child.next = child.prev = nil
214
+ child.parent = self
215
+ else
216
+ @first_child.prepend_sibling child
217
+ end
218
+ end
219
+
220
+ alias << append_child
221
+
222
+ # Extract
223
+ #
224
+ # Extracts the node and its subtree from the larger structure.
225
+
226
+ def extract
227
+ return self if root?
228
+
229
+ if last?
230
+ parent.last_child = @prev
231
+ else
232
+ @next.prev = @prev
233
+ end
234
+
235
+ if first?
236
+ parent.first_child = @next
237
+ else
238
+ @prev.next = @next
239
+ end
240
+
241
+ @prev = @next = @parent = nil
242
+ self
243
+ end
244
+
245
+ # Delete
246
+ #
247
+ # Removes the node from the tree.
248
+
249
+ def delete
250
+ extract.children.map do |child|
251
+ child.parent = nil
252
+ child
253
+ end
254
+ end
255
+
256
+ # Ancestors
257
+ #
258
+ # Returns an enumerator that will iterate over the parents of this node
259
+ # until the root is reached.
260
+ #
261
+ # If a block is given it will be yielded to.
262
+
263
+ def ancestors
264
+ return to_enum(__callee__) unless block_given?
265
+ node = self
266
+ loop do
267
+ node = node.parent
268
+ yield node
269
+ end
270
+ end
271
+
272
+ # Children
273
+ #
274
+ # Returns an enumerator that will iterate over each of the node children.
275
+ # The default order is left-to-right, but by passing rtl: true the order can
276
+ # be reversed.
277
+ #
278
+ # If a block is given it will be yielded to.
279
+
280
+ def children(rtl: false)
281
+ return to_enum(__callee__, rtl: rtl) unless block_given?
282
+ return if leaf?
283
+
284
+ child, advance = if rtl
285
+ [@last_child, :prev]
286
+ else
287
+ [@first_child, :next]
288
+ end
289
+
290
+ loop do
291
+ yield child
292
+ child = child.send advance
293
+ end
294
+ end
295
+
296
+ # Each
297
+ #
298
+ #
299
+
300
+ def each(&block)
301
+ return to_enum(__callee__) unless block_given?
302
+ yield self
303
+ children { |v| v.each(&block) }
304
+ end
305
+
306
+ # Leafs
307
+ #
308
+ # Iterates over each of the leafs.
309
+
310
+ def leafs(rtl: false, &block)
311
+ return to_enum(__callee__, rtl: rtl) unless block_given?
312
+ return yield self if leaf?
313
+ children(rtl: rtl) { |v| v.leafs(rtl: rtl, &block) }
314
+ end
315
+
316
+ # Edges
317
+ #
318
+ # Iterates over each of the edges.
319
+
320
+ def edges(&block)
321
+ return to_enum(__callee__) unless block_given?
322
+
323
+ children do |v|
324
+ yield self, v
325
+ v.edges(&block)
326
+ end
327
+ end
328
+
329
+ # Add
330
+ #
331
+ # Add two roots together to create a larger tree. A new common root will be
332
+ # created and returned.
333
+
334
+ def +(other)
335
+ unless root? && other.root?
336
+ raise StructureException, 'Only roots can be added'
337
+ end
338
+
339
+ root = self.class.new
340
+ root << self << other
341
+ end
342
+
343
+ # Equality
344
+ #
345
+ # Returns true if the two vertecies form identical subtrees
346
+
347
+ def ==(other)
348
+ return false unless other.is_a? self.class
349
+ return other.leaf? if leaf?
350
+
351
+ children.to_a == other.children.to_a
352
+ end
353
+
354
+ # Tree
355
+ #
356
+ # Wraps the entire tree in a Tree object If this node is a child the root
357
+ # will be found and passed to Tree.new.
358
+
359
+ def tree
360
+ Tree.new root
361
+ end
362
+
363
+ # Subtree!
364
+ #
365
+ # Extracts this node from the larger tree and wraps it in a Tree object.
366
+
367
+ def subtree!
368
+ Tree.new extract
369
+ end
370
+
371
+ # Subtree
372
+ #
373
+ # Duplicates this node and its descendants and wraps them in a Tree object.
374
+
375
+ def subtree
376
+ Tree.new dup
377
+ end
378
+
379
+ # Inspect
380
+ #
381
+ # Visalizes the tree structure in a style very similar to the cli tool tree.
382
+ # An example of the output can be seen below. Note that the output string
383
+ # contains unicode characters.
384
+ #
385
+ # Node:0x3ffd64c22abc
386
+ # |--Node:0x3ffd64c1fd30
387
+ # | |--Node:0x3ffd64c1f86c
388
+ # | +--Node:0x3ffd64c1f63c
389
+ # +--Entety:0x3ffd64c1f40c
390
+ #
391
+ # By passing `as_array: true` the method will instead return an array
392
+ # containing each of the output lines. The method also accepts a block
393
+ # which, if given, will be yielded to once for every node, and the output
394
+ # will be used as node labels instead of the default identifier.
395
+
396
+ def inspect(as_array: false, &block)
397
+ unless block_given?
398
+ block = proc { |v| format '%s:0x%0x', v.class.name, v.object_id }
399
+ end
400
+
401
+ res = [block.call(self)]
402
+
403
+ children do |child|
404
+ lines = child.inspect(as_array: true, &block).each
405
+ res << ((child.last? ? '└─╴' : '├─╴') + lines.next)
406
+ prep = child.last? ? '   ' : '│  '
407
+ loop { res << (prep + lines.next) }
408
+ end
409
+
410
+ as_array ? res : res.join("\n")
411
+ end
412
+ end
413
+ end
@@ -0,0 +1,20 @@
1
+ module RootedTree
2
+ class Tree
3
+ attr_reader :root
4
+
5
+ def initialize(node = Node.new)
6
+ @root = node.root
7
+ end
8
+
9
+ # Degree
10
+ #
11
+ # Returns the maximum degree (number of children) in the tree.
12
+
13
+ def degree
14
+ max_degree_node = root.each.max_by do |node|
15
+ node.degree
16
+ end
17
+ max_degree_node.degree
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RootedTree
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rooted_tree/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rooted_tree"
8
+ spec.version = RootedTree::VERSION
9
+ spec.authors = ["Sebastian Lindberg"]
10
+ spec.email = ["seb.lindberg@gmail.com"]
11
+
12
+ spec.summary = %q{A basic implementation of a tree data structure.}
13
+ spec.description = %q{This gem implements a rooted, ordered tree, with a focus on easy iteration over nodes and access to basic tree prperties.}
14
+ spec.homepage = "https://github.com/seblindberg/ruby-rooted_tree"
15
+ spec.license = "MIT"
16
+
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"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.12"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.0"
25
+ spec.add_development_dependency "coveralls", "~> 0.8"
26
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rooted_tree
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sebastian Lindberg
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-07-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: coveralls
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.8'
69
+ description: This gem implements a rooted, ordered tree, with a focus on easy iteration
70
+ over nodes and access to basic tree prperties.
71
+ email:
72
+ - seb.lindberg@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - examples/filesystem_tree.rb
86
+ - lib/rooted_tree.rb
87
+ - lib/rooted_tree/node.rb
88
+ - lib/rooted_tree/tree.rb
89
+ - lib/rooted_tree/version.rb
90
+ - rooted_tree.gemspec
91
+ homepage: https://github.com/seblindberg/ruby-rooted_tree
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.5.1
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: A basic implementation of a tree data structure.
115
+ test_files: []