rooted_tree 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []