rubytree 1.0.0 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +0 -7
- data/Gemfile.lock +69 -40
- data/LICENSE.md +1 -2
- data/README.md +1 -2
- data/Rakefile +18 -22
- data/examples/example_basic.rb +1 -1
- data/lib/rubytree.rb +1 -1
- data/lib/tree/binarytree.rb +7 -11
- data/lib/tree/utils/camel_case_method_handler.rb +7 -10
- data/lib/tree/utils/hash_converter.rb +60 -64
- data/lib/tree/utils/json_converter.rb +10 -15
- data/lib/tree/utils/metrics_methods.rb +8 -7
- data/lib/tree/utils/path_methods.rb +3 -7
- data/lib/tree/utils/tree_merge_handler.rb +5 -7
- data/lib/tree/utils/utils.rb +2 -4
- data/lib/tree/version.rb +2 -3
- data/lib/tree.rb +99 -85
- data/rubytree.gemspec +90 -0
- data/setup.rb +1565 -0
- data/spec/tree_spec.rb +0 -2
- data/test/test_binarytree.rb +21 -22
- data/test/test_rubytree_require.rb +0 -2
- data/test/test_subclassed_node.rb +0 -4
- data/test/test_thread_and_fiber.rb +7 -10
- data/test/test_tree.rb +201 -203
- metadata +86 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e9977428c2a28cf7d3a31ccc91047f646ec88c4f0da90663e9596dfb006ce0c6
|
4
|
+
data.tar.gz: 0e3a42cf9214d95e5f9deed0511c6728c5204a03a319b30a80d96daf3f20f505
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f311eec1cf9a9710cb5905e5c7c691344bd60beb57b472462d40a81e12af475bb6bf328a6502aa8bbb9af17d5d350b163b5d8d36888835866c473b9ea6e13953
|
7
|
+
data.tar.gz: fdc9890aaf6e298d4400ee6f84398ced73dfdaf93c6fe87a4981dd35c5f17934e2a01e803d44351724c615f11e075fbf3181403cbb4343005452ee47fdfbe25e
|
data/Gemfile
CHANGED
@@ -3,13 +3,6 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in rubytree.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
group :development, :test do
|
7
|
-
gem 'rake', '~> 10.4'
|
8
|
-
gem 'test-unit', '~> 3.0'
|
9
|
-
gem 'coveralls', '>= 0.7', :require => false, :platforms => :mri_21
|
10
|
-
gem 'rspec', '>= 3.4'
|
11
|
-
end
|
12
|
-
|
13
6
|
# Local Variables:
|
14
7
|
# mode: ruby
|
15
8
|
# End:
|
data/Gemfile.lock
CHANGED
@@ -1,68 +1,97 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubytree (1.0.
|
5
|
-
json (~> 2.1)
|
6
|
-
structured_warnings (~> 0.
|
4
|
+
rubytree (1.0.2)
|
5
|
+
json (~> 2.6.1)
|
6
|
+
structured_warnings (~> 0.4.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
|
11
|
+
ast (2.4.2)
|
12
|
+
coveralls (0.8.23)
|
12
13
|
json (>= 1.8, < 3)
|
13
|
-
simplecov (~> 0.
|
14
|
+
simplecov (~> 0.16.1)
|
14
15
|
term-ansicolor (~> 1.3)
|
15
|
-
thor (
|
16
|
+
thor (>= 0.19.4, < 2.0)
|
16
17
|
tins (~> 1.6)
|
17
|
-
diff-lcs (1.
|
18
|
-
docile (1.
|
19
|
-
json (2.1
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
18
|
+
diff-lcs (1.5.0)
|
19
|
+
docile (1.4.0)
|
20
|
+
json (2.6.1)
|
21
|
+
parallel (1.21.0)
|
22
|
+
parser (3.0.3.2)
|
23
|
+
ast (~> 2.4.1)
|
24
|
+
power_assert (2.0.1)
|
25
|
+
psych (4.0.3)
|
26
|
+
stringio
|
27
|
+
rainbow (3.0.0)
|
28
|
+
rake (13.0.6)
|
29
|
+
rdoc (6.4.0)
|
30
|
+
psych (>= 4.0.0)
|
31
|
+
regexp_parser (2.2.0)
|
32
|
+
rexml (3.2.5)
|
33
|
+
rspec (3.10.0)
|
34
|
+
rspec-core (~> 3.10.0)
|
35
|
+
rspec-expectations (~> 3.10.0)
|
36
|
+
rspec-mocks (~> 3.10.0)
|
37
|
+
rspec-core (3.10.1)
|
38
|
+
rspec-support (~> 3.10.0)
|
39
|
+
rspec-expectations (3.10.1)
|
30
40
|
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
-
rspec-support (~> 3.
|
32
|
-
rspec-mocks (3.
|
41
|
+
rspec-support (~> 3.10.0)
|
42
|
+
rspec-mocks (3.10.2)
|
33
43
|
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
-
rspec-support (~> 3.
|
35
|
-
rspec-support (3.
|
44
|
+
rspec-support (~> 3.10.0)
|
45
|
+
rspec-support (3.10.3)
|
36
46
|
rtags (0.97)
|
37
47
|
rtagstask (0.0.4)
|
38
48
|
rtags (> 0.0.0)
|
39
|
-
|
40
|
-
|
49
|
+
rubocop (1.24.0)
|
50
|
+
parallel (~> 1.10)
|
51
|
+
parser (>= 3.0.0.0)
|
52
|
+
rainbow (>= 2.2.2, < 4.0)
|
53
|
+
regexp_parser (>= 1.8, < 3.0)
|
54
|
+
rexml
|
55
|
+
rubocop-ast (>= 1.15.0, < 2.0)
|
56
|
+
ruby-progressbar (~> 1.7)
|
57
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
58
|
+
rubocop-ast (1.15.1)
|
59
|
+
parser (>= 3.0.1.1)
|
60
|
+
ruby-progressbar (1.11.0)
|
61
|
+
simplecov (0.16.1)
|
62
|
+
docile (~> 1.1)
|
41
63
|
json (>= 1.8, < 3)
|
42
64
|
simplecov-html (~> 0.10.0)
|
43
65
|
simplecov-html (0.10.2)
|
44
|
-
|
45
|
-
|
66
|
+
stringio (3.0.1)
|
67
|
+
structured_warnings (0.4.0)
|
68
|
+
sync (0.5.0)
|
69
|
+
term-ansicolor (1.7.1)
|
46
70
|
tins (~> 1.0)
|
47
|
-
test-unit (3.
|
71
|
+
test-unit (3.5.3)
|
48
72
|
power_assert
|
49
|
-
thor (
|
50
|
-
tins (1.
|
51
|
-
|
73
|
+
thor (1.1.0)
|
74
|
+
tins (1.30.0)
|
75
|
+
sync
|
76
|
+
unicode-display_width (2.1.0)
|
77
|
+
webrick (1.7.0)
|
78
|
+
yard (0.9.27)
|
79
|
+
webrick (~> 1.7.0)
|
52
80
|
|
53
81
|
PLATFORMS
|
54
82
|
ruby
|
55
83
|
|
56
84
|
DEPENDENCIES
|
57
|
-
bundler (~>
|
58
|
-
coveralls (>= 0.
|
59
|
-
rake (
|
60
|
-
rdoc (
|
61
|
-
rspec (
|
62
|
-
rtagstask (~> 0.0)
|
85
|
+
bundler (~> 2.3.4)
|
86
|
+
coveralls (>= 0.8.23)
|
87
|
+
rake (>= 13.0.6)
|
88
|
+
rdoc (>= 6.4.0)
|
89
|
+
rspec (~> 3.10.0)
|
90
|
+
rtagstask (~> 0.0.4)
|
91
|
+
rubocop (>= 1.24.0)
|
63
92
|
rubytree!
|
64
|
-
test-unit (
|
65
|
-
yard (~> 0.9)
|
93
|
+
test-unit (>= 3.5.3)
|
94
|
+
yard (~> 0.9.27)
|
66
95
|
|
67
96
|
BUNDLED WITH
|
68
|
-
|
97
|
+
2.3.4
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
<!--
|
2
2
|
README.md
|
3
3
|
|
4
|
-
Copyright (C) 2006-2017 Anupam Sengupta (anupamsg@gmail.com)
|
4
|
+
Copyright (C) 2006-2017, 2020 Anupam Sengupta (anupamsg@gmail.com)
|
5
5
|
|
6
6
|
-->
|
7
7
|
# **RubyTree** #
|
8
8
|
|
9
9
|
[![Gem Version](https://badge.fury.io/rb/rubytree.png)](http://badge.fury.io/rb/rubytree)
|
10
10
|
[![Travis Build Status](https://secure.travis-ci.org/evolve75/RubyTree.png)](http://travis-ci.org/evolve75/rubytree)
|
11
|
-
[![Dependency Status](https://gemnasium.com/evolve75/RubyTree.png)](https://gemnasium.com/evolve75/RubyTree)
|
12
11
|
[![Code Climate](https://codeclimate.com/github/evolve75/RubyTree.png)](https://codeclimate.com/github/evolve75/RubyTree)
|
13
12
|
[![Coverage Status](https://coveralls.io/repos/evolve75/RubyTree/badge.png)](https://coveralls.io/r/evolve75/RubyTree)
|
14
13
|
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Rakefile - This file is part of the RubyTree package.
|
4
4
|
#
|
5
|
-
# Copyright (c) 2006-
|
5
|
+
# Copyright (c) 2006-2021 Anupam Sengupta
|
6
6
|
#
|
7
7
|
# All rights reserved.
|
8
8
|
#
|
@@ -55,18 +55,18 @@ task :version do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
require 'rake/clean'
|
58
|
-
task :
|
58
|
+
task clean: 'gem:clobber_package'
|
59
59
|
CLEAN.include('coverage')
|
60
|
-
task :
|
60
|
+
task clobber: [:clean, 'doc:clobber_rdoc', 'doc:clobber_yard']
|
61
61
|
|
62
62
|
desc 'Open an irb session preloaded with this library'
|
63
63
|
task :console do
|
64
64
|
sh 'irb -rubygems -r ./lib/tree.rb'
|
65
65
|
end
|
66
66
|
|
67
|
-
namespace :doc do
|
67
|
+
namespace :doc do # ................................ Documentation
|
68
68
|
begin
|
69
|
-
gem 'rdoc', '>=
|
69
|
+
gem 'rdoc', '>= 6.4.0' # To get around a stupid bug in Ruby 1.9.2 Rake.
|
70
70
|
require 'rdoc/task'
|
71
71
|
Rake::RDocTask.new do |rdoc|
|
72
72
|
rdoc.rdoc_dir = 'rdoc'
|
@@ -83,7 +83,7 @@ namespace :doc do # ................................ Documentation
|
|
83
83
|
require 'yard'
|
84
84
|
YARD::Rake::YardocTask.new do |t|
|
85
85
|
t.files = ['lib/**/*.rb', '-', GEM_SPEC.extra_rdoc_files]
|
86
|
-
t.options = %w
|
86
|
+
t.options = %w[--no-private --embed-mixins]
|
87
87
|
end
|
88
88
|
rescue LoadError
|
89
89
|
# Oh well.
|
@@ -96,10 +96,9 @@ namespace :doc do # ................................ Documentation
|
|
96
96
|
end
|
97
97
|
|
98
98
|
desc 'Run the test cases'
|
99
|
-
task :
|
100
|
-
|
101
|
-
namespace :test do # ................................ Test related
|
99
|
+
task test: 'test:unit'
|
102
100
|
|
101
|
+
namespace :test do # ................................ Test related
|
103
102
|
require 'rake/testtask'
|
104
103
|
Rake::TestTask.new(:unit) do |test|
|
105
104
|
test.libs << 'lib' << 'test'
|
@@ -131,10 +130,9 @@ namespace :test do # ................................ Test related
|
|
131
130
|
rescue LoadError
|
132
131
|
# Oh well. Can't have everything.
|
133
132
|
end
|
134
|
-
|
135
133
|
end
|
136
134
|
|
137
|
-
begin
|
135
|
+
begin # ................................ rspec tests
|
138
136
|
require 'rspec/core/rake_task'
|
139
137
|
|
140
138
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
@@ -145,17 +143,15 @@ rescue LoadError
|
|
145
143
|
# Cannot load rspec.
|
146
144
|
end
|
147
145
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
CLEAN.include('TAGS')
|
154
|
-
end
|
155
|
-
rescue LoadError
|
156
|
-
# Oh well. Can't have everything.
|
146
|
+
namespace :tag do # ................................ Emacs Tags
|
147
|
+
require 'rtagstask'
|
148
|
+
RTagsTask.new(:tags) do |rd|
|
149
|
+
rd.vi = false
|
150
|
+
CLEAN.include('TAGS')
|
157
151
|
end
|
158
|
-
|
152
|
+
rescue LoadError
|
153
|
+
# Oh well. Can't have everything.
|
154
|
+
end
|
159
155
|
|
160
156
|
namespace :gem do # ................................ Gem related
|
161
157
|
require 'rubygems/package_task'
|
@@ -165,7 +161,7 @@ namespace :gem do # ................................ Gem related
|
|
165
161
|
end
|
166
162
|
|
167
163
|
desc 'Push the gem into the Rubygems repository'
|
168
|
-
task :
|
164
|
+
task push: :gem do
|
169
165
|
sh "gem push pkg/#{GEM_NAME}"
|
170
166
|
end
|
171
167
|
end
|
data/examples/example_basic.rb
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
# +---------------+
|
24
24
|
|
25
25
|
# ..... Example starts.
|
26
|
-
require 'tree'
|
26
|
+
require 'tree' # Load the library
|
27
27
|
|
28
28
|
# ..... Create the root node first. Note that every node has a name and an optional content payload.
|
29
29
|
root_node = Tree::TreeNode.new('ROOT', 'Root Content')
|
data/lib/rubytree.rb
CHANGED
data/lib/tree/binarytree.rb
CHANGED
@@ -41,7 +41,6 @@
|
|
41
41
|
require_relative '../tree'
|
42
42
|
|
43
43
|
module Tree
|
44
|
-
|
45
44
|
# Provides a Binary tree implementation. This node allows only two child nodes
|
46
45
|
# (left and right child). It also provides direct access to the left or right
|
47
46
|
# child, including assignment to the same.
|
@@ -51,7 +50,6 @@ module Tree
|
|
51
50
|
# @author Anupam Sengupta
|
52
51
|
#
|
53
52
|
class BinaryTreeNode < TreeNode
|
54
|
-
|
55
53
|
# @!group Core Attributes
|
56
54
|
|
57
55
|
# @!attribute [rw] left_child
|
@@ -85,6 +83,7 @@ module Tree
|
|
85
83
|
# @return [Boolean] +true+ if this is the left child of its parent.
|
86
84
|
def is_left_child?
|
87
85
|
return false if is_root?
|
86
|
+
|
88
87
|
self == parent.left_child
|
89
88
|
end
|
90
89
|
|
@@ -95,6 +94,7 @@ module Tree
|
|
95
94
|
# @return [Boolean] +true+ if this is the right child of its parent.
|
96
95
|
def is_right_child?
|
97
96
|
return false if is_root?
|
97
|
+
|
98
98
|
self == parent.right_child
|
99
99
|
end
|
100
100
|
|
@@ -119,7 +119,6 @@ module Tree
|
|
119
119
|
super(child)
|
120
120
|
end
|
121
121
|
|
122
|
-
|
123
122
|
# Instantiate and insert child nodes from data in a Ruby +Hash+
|
124
123
|
#
|
125
124
|
# This method is used in conjunction with {Tree::TreeNode.from_hash} to
|
@@ -152,6 +151,7 @@ module Tree
|
|
152
151
|
def add_from_hash(hashed_subtree)
|
153
152
|
raise ArgumentError, 'Too many children'\
|
154
153
|
if hashed_subtree.size + @children.size > 2
|
154
|
+
|
155
155
|
super(hashed_subtree)
|
156
156
|
end
|
157
157
|
|
@@ -170,14 +170,13 @@ module Tree
|
|
170
170
|
# @see #preordered_each
|
171
171
|
# @see #postordered_each
|
172
172
|
# noinspection RubyUnusedLocalVariable
|
173
|
-
def inordered_each
|
174
|
-
|
175
|
-
return self.to_enum unless block_given?
|
173
|
+
def inordered_each
|
174
|
+
return to_enum unless block_given?
|
176
175
|
|
177
176
|
node_stack = []
|
178
177
|
current_node = self
|
179
178
|
|
180
|
-
until node_stack.empty? and current_node
|
179
|
+
until node_stack.empty? and current_node.nil?
|
181
180
|
if current_node
|
182
181
|
node_stack.push(current_node)
|
183
182
|
current_node = current_node.left_child
|
@@ -189,7 +188,6 @@ module Tree
|
|
189
188
|
end
|
190
189
|
|
191
190
|
self if block_given?
|
192
|
-
|
193
191
|
end
|
194
192
|
|
195
193
|
# A protected method to allow insertion of child nodes at the specified
|
@@ -245,9 +243,7 @@ module Tree
|
|
245
243
|
|
246
244
|
# Swaps the left and right child nodes of the receiver node with each other.
|
247
245
|
def swap_children
|
248
|
-
self.left_child, self.right_child =
|
246
|
+
self.left_child, self.right_child = right_child, left_child
|
249
247
|
end
|
250
|
-
|
251
248
|
end
|
252
|
-
|
253
249
|
end
|
@@ -4,9 +4,9 @@
|
|
4
4
|
#
|
5
5
|
# Author:: Anupam Sengupta (anupamsg@gmail.com)
|
6
6
|
#
|
7
|
-
# Time-stamp: <
|
7
|
+
# Time-stamp: <2021-12-29 13:02:04 anupam>
|
8
8
|
#
|
9
|
-
# Copyright (C) 2012, 2013, 2015, 2017 Anupam Sengupta <anupamsg@gmail.com>
|
9
|
+
# Copyright (C) 2012, 2013, 2015, 2017, 2021 Anupam Sengupta <anupamsg@gmail.com>
|
10
10
|
#
|
11
11
|
# All rights reserved.
|
12
12
|
#
|
@@ -36,19 +36,18 @@
|
|
36
36
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
37
|
#
|
38
38
|
|
39
|
-
require_relative '../../../lib/tree'
|
40
39
|
require 'structured_warnings'
|
41
40
|
|
42
41
|
module Tree::Utils
|
43
42
|
# Provides utility functions to handle CamelCase methods, and redirect
|
44
43
|
# invocation of such methods to the snake_case equivalents.
|
45
44
|
module CamelCaseMethodHandler
|
46
|
-
def self.included(
|
45
|
+
def self.included(_base)
|
47
46
|
# @!visibility private
|
48
47
|
# Allow the deprecated CamelCase method names. Display a warning.
|
49
48
|
# :nodoc:
|
50
49
|
def method_missing(meth, *args, &blk)
|
51
|
-
if
|
50
|
+
if respond_to?((new_method_name = to_snake_case(meth)))
|
52
51
|
warn StructuredWarnings::DeprecatedMethodWarning,
|
53
52
|
'The camelCased methods are deprecated. ' +
|
54
53
|
"Please use #{new_method_name} instead of #{meth}"
|
@@ -58,8 +57,6 @@ module Tree::Utils
|
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
|
-
protected
|
62
|
-
|
63
60
|
# @!visibility private
|
64
61
|
# Convert a CamelCasedWord to a underscore separated camel_cased_word.
|
65
62
|
#
|
@@ -68,13 +65,13 @@ module Tree::Utils
|
|
68
65
|
def to_snake_case(camel_cased_word)
|
69
66
|
word = camel_cased_word.to_s
|
70
67
|
word.gsub!(/::/, '/')
|
71
|
-
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
72
|
-
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
68
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
69
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
73
70
|
word.tr!('-', '_')
|
74
71
|
word.downcase!
|
75
72
|
word
|
76
73
|
end
|
77
|
-
|
74
|
+
protected :to_snake_case
|
78
75
|
end # self.included
|
79
76
|
end
|
80
77
|
end
|
@@ -40,7 +40,6 @@
|
|
40
40
|
require_relative '../../../lib/tree/utils/utils'
|
41
41
|
|
42
42
|
module Tree::Utils::HashConverter
|
43
|
-
|
44
43
|
def self.included(base)
|
45
44
|
base.extend(ClassMethods)
|
46
45
|
end
|
@@ -49,7 +48,6 @@ module Tree::Utils::HashConverter
|
|
49
48
|
# class methods on any class mixing in the {Tree::Utils::HashConverter}
|
50
49
|
# module.
|
51
50
|
module ClassMethods
|
52
|
-
|
53
51
|
# Factory method builds a {Tree::TreeNode} from a +Hash+.
|
54
52
|
#
|
55
53
|
# This method will interpret each key of your +Hash+ as a {Tree::TreeNode}.
|
@@ -102,76 +100,74 @@ module Tree::Utils::HashConverter
|
|
102
100
|
|
103
101
|
root, children = hash.first
|
104
102
|
|
105
|
-
unless [Hash, NilClass].include?(children.class)
|
106
|
-
raise ArgumentError, 'Invalid child. Must be nil or hash.'
|
107
|
-
end
|
103
|
+
raise ArgumentError, 'Invalid child. Must be nil or hash.' unless [Hash, NilClass].include?(children.class)
|
108
104
|
|
109
|
-
node =
|
105
|
+
node = new(*root)
|
110
106
|
node.add_from_hash(children) unless children.nil?
|
111
107
|
node
|
112
108
|
end
|
113
109
|
end
|
114
110
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
child_nodes
|
111
|
+
# Instantiate and insert child nodes from data in a Ruby +Hash+
|
112
|
+
#
|
113
|
+
# This method is used in conjunction with from_hash to provide a
|
114
|
+
# convenient way of building and inserting child nodes present in a Ruby
|
115
|
+
# hashes.
|
116
|
+
#
|
117
|
+
# This method will instantiate a node instance for each top-
|
118
|
+
# level key of the input hash, to be inserted as children of the receiver
|
119
|
+
# instance.
|
120
|
+
#
|
121
|
+
# Nested hashes are expected and further child nodes will be created and
|
122
|
+
# added accordingly. If a hash key is a single value that value will be
|
123
|
+
# used as the name for the node. If a hash key is an Array, both node
|
124
|
+
# name and content will be populated.
|
125
|
+
#
|
126
|
+
# A leaf element of the tree should be represented as a hash key with
|
127
|
+
# corresponding value +nil+ or {}.
|
128
|
+
#
|
129
|
+
# @example
|
130
|
+
# root = Tree::TreeNode.new(:A, "Root content!")
|
131
|
+
# root.add_from_hash({:B => {:D => {}}, [:C, "C content!"] => {}})
|
132
|
+
#
|
133
|
+
# @author Jen Hamon (http://www.github.com/jhamon)
|
134
|
+
# @param [Hash] children The hash of child subtrees.
|
135
|
+
# @raise [ArgumentError] This exception is raised if a non-hash is passed.
|
136
|
+
# @return [Array] Array of child nodes added
|
137
|
+
# @see ClassMethods#from_hash
|
138
|
+
def add_from_hash(children)
|
139
|
+
raise ArgumentError, 'Argument must be a type of hash'\
|
140
|
+
unless children.is_a?(Hash)
|
141
|
+
|
142
|
+
child_nodes = []
|
143
|
+
children.each do |child, grandchildren|
|
144
|
+
child_node = self.class.from_hash({ child => grandchildren })
|
145
|
+
child_nodes << child_node
|
146
|
+
self << child_node
|
154
147
|
end
|
155
148
|
|
156
|
-
|
157
|
-
|
158
|
-
# @example
|
159
|
-
# root = Tree::TreeNode.new(:root, "root content")
|
160
|
-
# root << Tree::TreeNode.new(:child1, "child1 content")
|
161
|
-
# root << Tree::TreeNode.new(:child2, "child2 content")
|
162
|
-
# root.to_h # => {[:root, "root content"] =>
|
163
|
-
# { [:child1, "child1 content"] =>
|
164
|
-
# {}, [:child2, "child2 content"] => {}}}
|
165
|
-
# @author Jen Hamon (http://www.github.com/jhamon)
|
166
|
-
# @return [Hash] Hash representation of tree.
|
167
|
-
def to_h
|
168
|
-
key = has_content? ? [name, content] : name
|
169
|
-
|
170
|
-
children_hash = {}
|
171
|
-
children do |child|
|
172
|
-
children_hash.merge! child.to_h
|
173
|
-
end
|
149
|
+
child_nodes
|
150
|
+
end
|
174
151
|
|
175
|
-
|
152
|
+
# Convert a node and its subtree into a Ruby hash.
|
153
|
+
#
|
154
|
+
# @example
|
155
|
+
# root = Tree::TreeNode.new(:root, "root content")
|
156
|
+
# root << Tree::TreeNode.new(:child1, "child1 content")
|
157
|
+
# root << Tree::TreeNode.new(:child2, "child2 content")
|
158
|
+
# root.to_h # => {[:root, "root content"] =>
|
159
|
+
# { [:child1, "child1 content"] =>
|
160
|
+
# {}, [:child2, "child2 content"] => {}}}
|
161
|
+
# @author Jen Hamon (http://www.github.com/jhamon)
|
162
|
+
# @return [Hash] Hash representation of tree.
|
163
|
+
def to_h
|
164
|
+
key = has_content? ? [name, content] : name
|
165
|
+
|
166
|
+
children_hash = {}
|
167
|
+
children do |child|
|
168
|
+
children_hash.merge! child.to_h
|
176
169
|
end
|
170
|
+
|
171
|
+
{ key => children_hash }
|
172
|
+
end
|
177
173
|
end
|
@@ -41,7 +41,6 @@ require 'json'
|
|
41
41
|
# Provides utility methods to convert a {Tree::TreeNode} to and from
|
42
42
|
# JSON[http://flori.github.com/json/].
|
43
43
|
module Tree::Utils::JSONConverter
|
44
|
-
|
45
44
|
def self.included(base)
|
46
45
|
base.extend(ClassMethods)
|
47
46
|
end
|
@@ -63,20 +62,16 @@ module Tree::Utils::JSONConverter
|
|
63
62
|
# @see #to_json
|
64
63
|
# @see http://stackoverflow.com/a/6880638/273808
|
65
64
|
# noinspection RubyUnusedLocalVariable
|
66
|
-
def as_json(
|
67
|
-
|
65
|
+
def as_json(_options = {})
|
68
66
|
json_hash = {
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
name: name,
|
68
|
+
content: content,
|
69
|
+
JSON.create_id => self.class.name
|
72
70
|
}
|
73
71
|
|
74
|
-
if has_children?
|
75
|
-
json_hash['children'] = children
|
76
|
-
end
|
72
|
+
json_hash['children'] = children if has_children?
|
77
73
|
|
78
74
|
json_hash
|
79
|
-
|
80
75
|
end
|
81
76
|
|
82
77
|
# Creates a JSON representation of this node including all it's children.
|
@@ -117,15 +112,15 @@ module Tree::Utils::JSONConverter
|
|
117
112
|
# @see #to_json
|
118
113
|
# @see http://flori.github.com/json
|
119
114
|
def json_create(json_hash)
|
120
|
-
|
121
115
|
node = new(json_hash['name'], json_hash['content'])
|
122
116
|
|
123
|
-
json_hash['children']
|
124
|
-
|
125
|
-
|
117
|
+
if json_hash['children']
|
118
|
+
json_hash['children'].each do |child|
|
119
|
+
node << child
|
120
|
+
end
|
121
|
+
end
|
126
122
|
|
127
123
|
node
|
128
|
-
|
129
124
|
end
|
130
125
|
end
|
131
126
|
end
|