rubytree 1.0.0 → 1.0.2
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 +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
|
[](http://badge.fury.io/rb/rubytree)
|
10
10
|
[](http://travis-ci.org/evolve75/rubytree)
|
11
|
-
[](https://gemnasium.com/evolve75/RubyTree)
|
12
11
|
[](https://codeclimate.com/github/evolve75/RubyTree)
|
13
12
|
[](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
|