hash_base 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes and ruby arrays
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Array
23
+
24
+ ########################################################################################
25
+ #
26
+ # to_html: creates a html table from a rectangular array
27
+ #
28
+ # options: headings: true/false, footer: true/false
29
+ #
30
+ ########################################################################################
31
+ def to_html(options={}, &block)
32
+
33
+ options[:table] = options[:table].to_h.merge({:class => options[:table_class]}.compact) # support legacy
34
+
35
+ t = dup
36
+ body = t
37
+ head, body = [t.shift, t] if options[:headings]
38
+ foot, body = [t.pop , t] if options[:footer]
39
+
40
+ html_tag(:table, options[:table].to_h.compact) do
41
+ [head].compact.table_row_group(options.merge(:row_group => {:type => :thead}, :cell => {:type => :th}), &block) +
42
+ body.compact.table_row_group(options.merge(:row_group => {:type => :tbody}, :cell => {:type => :td}), &block) +
43
+ [foot].compact.table_row_group(options.merge(:row_group => {:type => :tfoot}, :cell => {:type => :td}), &block)
44
+ end
45
+ end #def
46
+
47
+
48
+ def table_row_group(options={}, &block)
49
+ rows = collect.with_index do |row, row_index|
50
+ row.table_row(row_index, options, &block)
51
+ end.join("")
52
+ rows.present? ? html_tag(options.dig(:row_group, :type) || :tbody, rows) : ""
53
+ end #def
54
+
55
+ def table_row(row_index, options={}, &block)
56
+ html_tag(:tr, options[:row].to_h.compact) do
57
+ row = collect.with_index do |value, column_index|
58
+ html_tag(options.dig(:cell, :type) || :td, options[:cell].to_h.except(:type).compact) do
59
+ cell_value = if block_given?
60
+ yield value, column_index, row_index
61
+ else
62
+ style_value(value, options)
63
+ end
64
+ end #html_tag #cell_type
65
+ end.join("") #collect columns
66
+ row
67
+ end #html_tag #tr
68
+ end #def
69
+
70
+ ########################################################################################
71
+ private
72
+ ########################################################################################
73
+ def style_value(value, options={}, &block)
74
+ case value.class
75
+ when Integer
76
+ value.to_s
77
+ when Numeric
78
+ p = options[:precision] || 2
79
+ sprintf("%.#{p}f",value)
80
+ else
81
+ options[:html_safe] ? value.to_s : CGI::escapeHTML(value.to_s)
82
+ end
83
+ end #def
84
+
85
+ def html_tag(type, *content, &block)
86
+ if block_given?
87
+ opts = content.first.to_h.map{|k,v| " #{k}='#{v}'"}.join
88
+ "<#{type}#{opts}>#{yield block}</#{type}>"
89
+ else
90
+ opts = content[1].to_h.map{|k,v| " #{k}='#{v}'"}.join
91
+ "<#{type}#{opts}>#{content.first}</#{type}>"
92
+ end
93
+ end #def
94
+
95
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes and ruby arrays
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Array
23
+
24
+ ########################################################################################
25
+ #
26
+ # converts array of hashes to one hash with elements in array
27
+ #
28
+ ########################################################################################
29
+ class ArrayRowIsNotAHash < StandardError; end
30
+
31
+ def to_list
32
+ # test, if each element is a hash
33
+ each do |hash|
34
+ raise ArrayRowIsNotAHash unless hash.is_a?(Hash)
35
+ end
36
+ # extract all keys from all hashes
37
+ keys = map do |hash|
38
+ hash.keys
39
+ end.flatten.uniq
40
+ # now extract value for each key in each hash
41
+ map do |hash|
42
+ keys.map do |key|
43
+ hash[key]
44
+ end
45
+ end.unshift(keys)
46
+ end #def
47
+
48
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes and ruby arrays
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Array
23
+
24
+ ########################################################################################
25
+ #
26
+ # creates a table from a rectangular array, balanced with indent
27
+ #
28
+ # indent: (Integer) number of spaces for padding each table element
29
+ # precision (Integer) number of precision digits to print for floats
30
+ # padding (String) string between adjacing colums
31
+ ########################################################################################
32
+ def to_text(indent: 15, precision: 2, padding: " | " )
33
+ map do |line|
34
+ ln = line.is_a?(Array) ? line : [line]
35
+ ln.map do |e|
36
+ case e
37
+ when Integer
38
+ e.to_s.rjust(indent)
39
+ when Complex, Rational
40
+ e.to_s.rjust(indent)
41
+ when Numeric
42
+ sprintf("%.#{precision}f",e).rjust(indent)
43
+ else
44
+ e.to_s.ljust(indent)
45
+ end
46
+ end.join(padding)
47
+ end.join("\n")
48
+ end #def
49
+
50
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Hash
23
+
24
+ ########################################################################################
25
+ #
26
+ # apply(&block): applies block to deepest element, which is not a Hash
27
+ #
28
+ # -> hash
29
+ # new hash ->
30
+ #
31
+ ########################################################################################
32
+ def apply( &block )
33
+ return to_enum(:each) unless block_given?
34
+ hash = Hash.new
35
+ each do |key, value|
36
+ if value.is_a?(Hash)
37
+ hash[key] = value.apply( &block )
38
+ else
39
+ hash[key] = yield value
40
+ end
41
+ end
42
+ hash
43
+ end #def
44
+
45
+ ########################################################################################
46
+ #
47
+ # apply!(&block): applies block to deepest element, which is not a Hash
48
+ #
49
+ # -> hash
50
+ # same hash ->
51
+ #
52
+ ########################################################################################
53
+ def apply!( &block )
54
+ return to_enum(:each) unless block_given?
55
+ each do |key, value|
56
+ if value.is_a?(Hash)
57
+ self[key] = value.apply( &block )
58
+ else
59
+ self[key] = yield value
60
+ end
61
+ end
62
+ self
63
+ end #def
64
+
65
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Hash
23
+
24
+ ########################################################################################
25
+ #
26
+ # deep_values: gets an array of values of a nested hash as a flat array
27
+ #
28
+ # -> hash
29
+ # array ->
30
+ #
31
+ ########################################################################################
32
+ def deep_values
33
+ arr = Array.new
34
+ each do |key, value|
35
+ if value.is_a?(Hash)
36
+ arr += value.deep_values
37
+ else
38
+ arr << value
39
+ end
40
+ end #each
41
+ arr
42
+ end #def
43
+
44
+
45
+ ########################################################################################
46
+ #
47
+ # max_depth: gets max depth of a hash
48
+ #
49
+ # -> hash
50
+ # int ->
51
+ #
52
+ ########################################################################################
53
+ def max_depth(depth: 1)
54
+ max_depth = depth
55
+ each do |k,v|
56
+ if v.is_a?(Hash)
57
+ max_depth = [max_depth, v.max_depth( depth: depth + 1 )].max
58
+ end
59
+ end
60
+ max_depth
61
+ end #def
62
+
63
+ ########################################################################################
64
+ #
65
+ # deep_diff: compares two hashes - counter part to Array.deep_diff
66
+ # source: stackoverflow
67
+ #
68
+ ########################################################################################
69
+ def deep_diff(other, &block)
70
+ (self.keys + other.keys).uniq.inject({}) do |memo, key|
71
+ left = self[key]
72
+ right = other[key]
73
+
74
+ if block_given?
75
+ next memo if yield left, right
76
+ else
77
+ next memo if left == right
78
+ end
79
+ if left.respond_to?(:deep_diff) && right.respond_to?(:deep_diff)
80
+ memo[key] = left.deep_diff(right)
81
+ else
82
+ memo[key] = [left, right]
83
+ end
84
+
85
+ memo
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes and ruby arrays
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Hash
23
+
24
+ ########################################################################################
25
+ #
26
+ # group_by_positions: counter part to Array.group_by_positions
27
+ #
28
+ # will only be invoked by Array.group_by_positions
29
+ #
30
+ ########################################################################################
31
+ def group_by_positions( *positions )
32
+ ohash = ActiveSupport::OrderedHash.new
33
+ each do |key, val|
34
+ case val
35
+ when Hash, Array
36
+ ohash[key] = val.group_by_positions( *positions )
37
+ else
38
+ ohash[key] = val
39
+ end
40
+ end #each
41
+ ohash
42
+ end #def
43
+
44
+ ########################################################################################
45
+ #
46
+ # expand: reverse of group_by_positions
47
+ #
48
+ # -> nested_hash
49
+ # -> array
50
+ #
51
+ ########################################################################################
52
+ def expand(path_to_here=[])
53
+ arry = []
54
+ each do |k, v|
55
+ if v.is_a?(Hash)
56
+ arry += v.expand(path_to_here + [k])
57
+ elsif v.is_a?(Array)
58
+ v.each do |el|
59
+ arry << (path_to_here + [k] + el ) if el.is_a?(Array)
60
+ arry << (path_to_here + [k] + [el] ) unless el.is_a?(Array)
61
+ end
62
+ else
63
+ arry << (path_to_here + [k] + [v])
64
+ end
65
+ end
66
+ arry
67
+ end #def
68
+
69
+ end
@@ -0,0 +1,123 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes and ruby arrays
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Hash
23
+
24
+ ########################################################################################
25
+ #
26
+ # to_table: creates a rectangular table from a nested hash
27
+ #
28
+ # -> hash
29
+ # array ->
30
+ #
31
+ # parameters
32
+ #
33
+ # level: (Integer) only used internally for recursive calls (do not use)
34
+ # indent: (Integer) number of spaces for padding each table element
35
+ # precision (Integer) number of precision digits for floats
36
+ # dosort; (Boolean) should each level of keys be sorted ?
37
+ # content: (String) "style" => creates a table of cell styles, else table
38
+ # of data
39
+ # format: (String) "text" - text output, balanced with indent parameter
40
+ # "html" - html output
41
+ # total: (Proc) "-> x {x.flatten.inject(:+)}" proc to create totals of
42
+ # arrays of deepest values
43
+ # total_caption (String) caption for total line
44
+ # grand_total (Proc) "-> x {x.depp_values.flatten.inject(:+)}" proc to
45
+ # create totals of arrays of deepest values
46
+ # grant_total_caption (string) caption for grand total line
47
+ #
48
+ ########################################################################################
49
+ def to_table( level: 0, indent: 15, precision: 2, dosort: true, content: "data", format: nil, divisor: nil, total: nil, total_caption: "", grand_total: nil, grand_total_caption: "" )
50
+
51
+ arry = []
52
+ i = 0
53
+
54
+ h = dosort ? sort : self
55
+
56
+ h.each do |k, v|
57
+
58
+ first_line = Array.new( i > 0 ? level : 0) {""} + [k] unless content == "style"
59
+ first_line = Array.new( i > 0 ? level : 0) {|l| "empty level_#{l}"} + ["key level_#{level}"] if content == "style"
60
+
61
+ if v.is_a?(Hash)
62
+ lines = v.to_table(level: level + 1, content: content, indent: indent, dosort: dosort, divisor: divisor, total: total, total_caption: total_caption, grand_total: grand_total, grand_total_caption: grand_total_caption)
63
+ first_line += lines[0] # complement current line with last key
64
+ arry << first_line
65
+ arry += lines.drop(1) if lines.drop(1).present?
66
+ elsif v.is_a?(Array) #must be array
67
+ lines = []
68
+ v.each_with_index do |av, i|
69
+ elem = (av.is_a?(Array) ? av : [av])
70
+ lines << (Array.new( i > 0 ? level + 1 : 0) {""} + elem ) unless content == "style"
71
+ lines << (Array.new( i > 0 ? level + 1 : 0) {|l| "empty level_#{l}"} + Array.new(elem.length){"value level_#{level}"} ) if content == "style"
72
+ end
73
+ first_line += lines[0] # complement current line
74
+ arry << first_line
75
+ arry += lines.drop(1) if lines.drop(1).present?
76
+
77
+ max_len = arry.map{|r| r.length}.max
78
+
79
+ unless content == "style"
80
+ arry << (Array.new( max_len + 1) {divisor.to_s * indent} ) if total && divisor
81
+ arry << (["#{total_caption}"] + Array.new( max_len - 1) {""} + [total.yield(v)] ) if total
82
+ arry << (Array.new( max_len + 1) {""} ) if total && divisor
83
+ else
84
+ arry << (Array.new( max_len + 1) {|l| "divisor level_#{l}"} ) if total && divisor
85
+ arry << (["total_caption level_0"] + Array.new( max_len - 1) {|l| "empty level_#{l+1}"} + ["total level_#{level}"] ) if total
86
+ arry << (Array.new( max_len + 1) {|l| "empty level_#{l}"} ) if total && divisor
87
+ end
88
+ end
89
+ i+=1
90
+ end #each
91
+
92
+ if level == 0
93
+
94
+ max_len = arry.map{|r| r.length}.max
95
+
96
+ unless content == "style"
97
+ arry << (Array.new( max_len + 1 ) {divisor.to_s * indent} ) if grand_total && divisor
98
+ arry << (["#{grand_total_caption}"] + Array.new( max_len - 1 ) {""} + [grand_total.yield(self)] ) if grand_total
99
+ else
100
+ arry << (Array.new( max_len + 1) {"grand_total divisor"} ) if grand_total && divisor
101
+ arry << (["grand_total_caption level_0"] + Array.new( max_len - 1) {|l| "empty grand_total level_#{l+1}"} + ["grand_total"]) if grand_total
102
+ end
103
+
104
+
105
+ max_len = arry.map{|r| r.length}.max
106
+
107
+ arry.map!{|l| l += Array.new(max_len - l.length) {""} } unless content == "style"
108
+ arry.map!{|l| l += Array.new(max_len - l.length) {"empty padding"} } if content == "style"
109
+
110
+ if format == "text"
111
+ arry.to_text(indent: indent, precision: precision)
112
+ elsif format == "html"
113
+ arry.to_html( styles: self.to_table(content: "style", total: true, grand_total: true))
114
+ else
115
+ arry
116
+ end
117
+ else
118
+ arry
119
+ end
120
+
121
+ end #def
122
+
123
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ class Hash
23
+
24
+ ########################################################################################
25
+ #
26
+ # zip_out: puts elements into one zip file with keys as filenames
27
+ #
28
+ # -> hash
29
+ # zip ->
30
+ #
31
+ # depends on gem 'zip'
32
+ #
33
+ ########################################################################################
34
+ def zip_out(&block)
35
+
36
+ return nil unless defined?(Zip)
37
+
38
+ zip_stream = Zip::OutputStream.write_buffer do |zip|
39
+
40
+ each do |key, obj|
41
+ zip.put_next_entry(key)
42
+ if block_given?
43
+ zip.write(yield obj)
44
+ else
45
+ zip.write(obj)
46
+ end
47
+ end
48
+ end
49
+
50
+ # important - rewind the steam
51
+ zip_stream.rewind
52
+
53
+ # read out zip contents
54
+ zip_stream.read
55
+
56
+ end #def
57
+
58
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ #
3
+ # deep_try works like try, but with an arbitrary long list of methods
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module HashBase
23
+ VERSION = "0.1.6"
24
+ end
data/lib/hash_base.rb ADDED
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ #
3
+ # utilities for ruby hashes and ruby arrays
4
+ #
5
+ # Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ require "hash_base/hash/grouping"
23
+ require "hash_base/hash/apply"
24
+ require "hash_base/hash/deep_values"
25
+ require "hash_base/hash/to_table"
26
+ require "hash_base/hash/zip_out"
27
+
28
+ require "hash_base/array/grouping"
29
+ require "hash_base/array/to_html"
30
+ require "hash_base/array/to_list"
31
+ require "hash_base/array/to_text"