subhash 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +19 -0
- data/Rakefile +45 -8
- data/build/build_with_proxy.sh +53 -0
- data/files/bundle.sh +19 -0
- data/files/proxy.sh +23 -0
- data/lib/iarray.rb +365 -0
- data/lib/ihash.rb +605 -0
- data/lib/rh.rb +157 -0
- data/lib/subhash/version.rb +2 -2
- data/lib/subhash.rb +9 -825
- data/subhash.gemspec +10 -1
- metadata +37 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b002bfeab90a25d4208f184c8892ca90bd2a8761
|
4
|
+
data.tar.gz: df518060d1c2ae5f428b7eaa2302a6dd6cb8ba3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a183bffb2589c4f51b84de71436a2f562563e74b3a87f809471803303c490b9c005abc0320530c2c9f176c7f79bb0ed79e3fa3184e665b4699eeb237beeda106
|
7
|
+
data.tar.gz: 04f7c7a78f569b549a21f5b058109a2502b7225ae8f3976826de3b5c8d6f998259d8f8f4eedd3fc8ae9de8ba51bf2bc8dd33c38db0352d1a4e9b6dc9d89e99ca
|
data/Dockerfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
FROM centos:6
|
2
|
+
|
3
|
+
COPY files/proxy.sh /tmp/proxy.sh
|
4
|
+
RUN /tmp/proxy.sh
|
5
|
+
|
6
|
+
RUN yum -y install \
|
7
|
+
libffi-devel \
|
8
|
+
libxml2-devel \
|
9
|
+
libxslt-devel \
|
10
|
+
perl \
|
11
|
+
ruby \
|
12
|
+
rubygems \
|
13
|
+
ruby-devel \
|
14
|
+
; yum -y groupinstall "Development tools" \
|
15
|
+
; yum clean all
|
16
|
+
|
17
|
+
RUN gem install --no-rdoc --no-ri bundler && rm -fr /root/.gem
|
18
|
+
|
19
|
+
COPY files/bundle.sh /tmp/bundle.sh
|
data/Rakefile
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rspec/core/rake_task'
|
3
|
-
require 'rubocop/rake_task'
|
3
|
+
require 'rubocop/rake_task' unless RUBY_VERSION.match(/1\.8/)
|
4
4
|
require 'rdoc/task'
|
5
|
+
require 'json'
|
5
6
|
|
6
7
|
task :default => [:lint, :spec]
|
7
8
|
|
8
|
-
desc 'Run
|
9
|
-
|
9
|
+
desc 'Run all specs (locally + docker).'
|
10
|
+
task :spec => [:spec_local, :spec18]
|
11
|
+
|
12
|
+
desc 'Run acceptance test (docker - specs).'
|
13
|
+
task :acceptance => [:spec18]
|
14
|
+
|
15
|
+
desc 'Run the specs locally.'
|
16
|
+
RSpec::Core::RakeTask.new(:spec_local) do |t|
|
10
17
|
t.pattern = 'spec/*_spec.rb'
|
11
18
|
t.rspec_opts = '-f doc'
|
12
19
|
end
|
@@ -17,11 +24,41 @@ RDoc::Task.new do |rdoc|
|
|
17
24
|
rdoc.rdoc_files.include('README.md', 'lib', 'example', 'bin')
|
18
25
|
end
|
19
26
|
|
20
|
-
|
21
|
-
|
22
|
-
task
|
23
|
-
|
24
|
-
|
27
|
+
if RUBY_VERSION.match(/1\.8/)
|
28
|
+
desc 'no lint with ruby 1.8'
|
29
|
+
task :lint
|
30
|
+
else
|
31
|
+
desc 'Run RuboCop on the project'
|
32
|
+
RuboCop::RakeTask.new(:lint) do |task|
|
33
|
+
task.formatters = ['progress']
|
34
|
+
task.verbose = true
|
35
|
+
task.fail_on_error = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# rubocop: disable Style/SpecialGlobalVars
|
40
|
+
|
41
|
+
desc 'Run spec with docker for ruby 1.8'
|
42
|
+
task :spec18 do
|
43
|
+
begin
|
44
|
+
`docker`
|
45
|
+
rescue
|
46
|
+
puts 'Unable to run spec against ruby 1.8: docker not found'
|
47
|
+
else
|
48
|
+
system('build/build_with_proxy.sh -t ruby/1.8')
|
49
|
+
image_id = `docker images ruby/1.8`.split("\n")[1].split[2]
|
50
|
+
res = `docker inspect -f '{{json .}}' subhash`
|
51
|
+
c_img = ''
|
52
|
+
c_img = JSON.parse(res)['Image'][0..11] if $?.exitstatus == 0
|
53
|
+
|
54
|
+
if $?.exitstatus == 0 && image_id == c_img
|
55
|
+
system('docker start -ai subhash')
|
56
|
+
else
|
57
|
+
`docker rm subhash` if $?.exitstatus == 0
|
58
|
+
system('docker run -it --name subhash -v $(pwd):/src -w /src ruby/1.8 '\
|
59
|
+
'/tmp/bundle.sh')
|
60
|
+
end
|
61
|
+
end
|
25
62
|
end
|
26
63
|
|
27
64
|
task :build => [:lint, :spec]
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
function usage
|
18
|
+
{
|
19
|
+
echo "usage is $0 [--help][-t user/repo:version]
|
20
|
+
Script to build a docker image.
|
21
|
+
It takes your local setting of $http_proxy to build the image with the same proxy
|
22
|
+
If the proxy is not set, the docker image is simply executed, without proxy.
|
23
|
+
|
24
|
+
Options :
|
25
|
+
- help: is the current help
|
26
|
+
- t : Tag the image built. Respect the tag format use by docker -t option.
|
27
|
+
"
|
28
|
+
}
|
29
|
+
|
30
|
+
if [ "p$1" = "p--help" ]
|
31
|
+
then
|
32
|
+
usage
|
33
|
+
exit
|
34
|
+
fi
|
35
|
+
|
36
|
+
if [ "p$1" = "p-t" ] && [ "p$2" != "" ]
|
37
|
+
then
|
38
|
+
TAG="-t $2"
|
39
|
+
fi
|
40
|
+
|
41
|
+
if [ "$http_proxy" = "" ]
|
42
|
+
then
|
43
|
+
echo "Currently, no proxy is set. Running docker without proxy"
|
44
|
+
docker build $TAG
|
45
|
+
exit
|
46
|
+
fi
|
47
|
+
|
48
|
+
mkdir .tmp
|
49
|
+
awk '$0 ~ /RUN \/tmp\/proxy.sh/ { print "ENV http_proxy '"$http_proxy"'" }
|
50
|
+
$0 ~ // { print $0 } ' Dockerfile > .tmp/Dockerfile
|
51
|
+
cp -rp files tmp .tmp/
|
52
|
+
docker build $TAG .tmp
|
53
|
+
rm -fr .tmp
|
data/files/bundle.sh
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
cd /src
|
18
|
+
bundle
|
19
|
+
rake spec_local
|
data/files/proxy.sh
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
if [ "$http_proxy" != "" ]
|
18
|
+
then
|
19
|
+
echo "proxy setting to '$http_proxy'"
|
20
|
+
export http_proxy=$http_proxy
|
21
|
+
export https_proxy=$http_proxy
|
22
|
+
sed -i -e '/^\[main\]/aproxy='"$http_proxy" /etc/yum.conf
|
23
|
+
fi
|
data/lib/iarray.rb
ADDED
@@ -0,0 +1,365 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
# Defines rh_clone for Array
|
18
|
+
class Array
|
19
|
+
# Recursive Hash deep level found counter
|
20
|
+
# See details from #Hash.rh_lexist?
|
21
|
+
def rh_lexist?(*p)
|
22
|
+
p = p.flatten
|
23
|
+
|
24
|
+
return 0 if p.length == 0
|
25
|
+
|
26
|
+
key = p[0]
|
27
|
+
sp = p.drop(1)
|
28
|
+
|
29
|
+
return _lexist_array(sp, key) if key.is_a?(Fixnum)
|
30
|
+
|
31
|
+
_loop_lexist_array(sp, key)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Recursive Hash deep level existence
|
35
|
+
# See details at #Hash.rh_exist?
|
36
|
+
def rh_exist?(*p)
|
37
|
+
p = p.flatten
|
38
|
+
|
39
|
+
return nil if p.length == 0
|
40
|
+
|
41
|
+
count = p.length
|
42
|
+
(rh_lexist?(*p) == count)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Recursive Hash Get
|
46
|
+
# Please look to #Hash::rh_get for details about this function.
|
47
|
+
def rh_get(*p)
|
48
|
+
p = p.flatten
|
49
|
+
return self if p.length == 0
|
50
|
+
|
51
|
+
key = p[0]
|
52
|
+
sp = p.drop(1)
|
53
|
+
|
54
|
+
re, res, opts = _regexp(key)
|
55
|
+
return _keys_match(re, res, sp, opts) unless re.nil?
|
56
|
+
|
57
|
+
return _get_array(sp, key) if key.is_a?(Fixnum)
|
58
|
+
|
59
|
+
_loop_get_array(sp, key)
|
60
|
+
end
|
61
|
+
|
62
|
+
# return an exact clone of the recursive Array and Hash contents.
|
63
|
+
#
|
64
|
+
# * *Args* :
|
65
|
+
#
|
66
|
+
# * *Returns* :
|
67
|
+
# - Recursive Array/Hash cloned.
|
68
|
+
# * *Raises* :
|
69
|
+
# Nothing
|
70
|
+
#
|
71
|
+
# examples:
|
72
|
+
# hdata = { :test => { :test2 => { :test5 => :test,
|
73
|
+
# 'text' => 'blabla' },
|
74
|
+
# 'test5' => 'test' },
|
75
|
+
# :array => [{ :test => :value1 }, 2, { :test => :value3 }]}
|
76
|
+
#
|
77
|
+
# hclone = hdata.rh_clone
|
78
|
+
# hclone[:test] = "test"
|
79
|
+
# hdata[:test] == { :test2 => { :test5 => :test,'text' => 'blabla' }
|
80
|
+
# # => true
|
81
|
+
# hclone[:array].pop
|
82
|
+
# hdata[:array].length != hclone[:array].length
|
83
|
+
# # => true
|
84
|
+
# hclone[:array][0][:test] = "value2"
|
85
|
+
# hdata[:array][0][:test] != hclone[:array][0][:test]
|
86
|
+
# # => true
|
87
|
+
def rh_clone
|
88
|
+
result = []
|
89
|
+
each do |value|
|
90
|
+
begin
|
91
|
+
result << value.rh_clone
|
92
|
+
rescue
|
93
|
+
result << value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
result
|
97
|
+
end
|
98
|
+
|
99
|
+
# This function is part of the rh_merge functionnality adapted for Array.
|
100
|
+
#
|
101
|
+
# To provide Array recursivity, we uses the element index.
|
102
|
+
#
|
103
|
+
# **Warning!** If the Array order has changed (sort/random) the index changed
|
104
|
+
# and can generate unwanted result.
|
105
|
+
#
|
106
|
+
# To implement recursivity, and some specific Array management (add/remove)
|
107
|
+
# you have to create an Hash and insert it at position 0 in the 'self' Array.
|
108
|
+
#
|
109
|
+
# **Warning!** If you create an Array, where index 0 contains a Hash, this
|
110
|
+
# Hash will be considered as the Array control element.
|
111
|
+
# If the first index of your Array is not a Hash, an empty Hash will be
|
112
|
+
# inserted at position 0.
|
113
|
+
#
|
114
|
+
# 'data' has the same restriction then 'self' about the first element.
|
115
|
+
# 'data' can influence the rh_merge Array behavior, by updating the first
|
116
|
+
# element.
|
117
|
+
#
|
118
|
+
# The first Hash element has the following attributes:
|
119
|
+
#
|
120
|
+
# - :__struct_changing: Array of index which accepts to move from a structured
|
121
|
+
# data (Hash/Array) to another structure or type.
|
122
|
+
#
|
123
|
+
# Ex: Hash => Array, Array => Integer
|
124
|
+
#
|
125
|
+
# - :__protected: Array of index which protects against update from 'data'
|
126
|
+
#
|
127
|
+
# - :__remove: Array of elements to remove. each element are remove with
|
128
|
+
# Array.delete function. See Array delete function for details.
|
129
|
+
#
|
130
|
+
# - :__remove_index: Array of indexes to remove.
|
131
|
+
# Each element are removed with Array.delete_at function.
|
132
|
+
# It starts from the highest index until the lowest.
|
133
|
+
# See Array delete function for details.
|
134
|
+
#
|
135
|
+
# **NOTE**: __remove and __remove_index cannot be used together.
|
136
|
+
# if both are set, __remove is choosen
|
137
|
+
#
|
138
|
+
# **NOTE** : __remove* is executed before __add*
|
139
|
+
#
|
140
|
+
# - :__add: Array of elements to add. Those elements are systematically added
|
141
|
+
# at the end of the Array. See Array.<< for details.
|
142
|
+
#
|
143
|
+
# - :__add_index: Hash of index(key) + Array of data(value) to add.
|
144
|
+
# The index listed refer to merged 'self' Array. several elements with same
|
145
|
+
# index are grouply inserted in the index.
|
146
|
+
# ex:
|
147
|
+
# [:data3].rh_merge({:__add_index => [0 => [:data1, :data2]]})
|
148
|
+
# => [{}, :data1, :data2, :data3]
|
149
|
+
#
|
150
|
+
# **NOTE**: __add and __add_index cannot be used together.
|
151
|
+
# if both are set, __add is choosen
|
152
|
+
#
|
153
|
+
# How merge is executed:
|
154
|
+
#
|
155
|
+
# Starting at index 0, each index of 'data' and 'self' are used to compare
|
156
|
+
# indexed data.
|
157
|
+
# - If 'data' index 0 has not an Hash, the 'self' index 0 is just skipped.
|
158
|
+
# - If 'data' index 0 has the 'control' Hash, the array will be updated
|
159
|
+
# according to :__add and :__remove arrays.
|
160
|
+
# when done, those attributes are removed
|
161
|
+
#
|
162
|
+
# - For all next index (1 => 'data'.length), data are compared
|
163
|
+
#
|
164
|
+
# - If the 'data' length is > than 'self' length
|
165
|
+
# addtionnal indexed data are added to 'self'
|
166
|
+
#
|
167
|
+
# - If index element exist in both 'data' and 'self',
|
168
|
+
# 'self' indexed data is updated/merged according to control.
|
169
|
+
# 'data' indexed data can use :unset to remove the data at this index
|
170
|
+
# nil is also supported. But the index won't be removed. data will just
|
171
|
+
# be set to nil
|
172
|
+
#
|
173
|
+
# when all Arrays elements are merged, rh_merge will:
|
174
|
+
# - remove 'self' elements containing ':unset'
|
175
|
+
#
|
176
|
+
# - merge 'self' data at index 0 with 'data' found index 0
|
177
|
+
#
|
178
|
+
def rh_merge(data)
|
179
|
+
_rh_merge(clone, data)
|
180
|
+
end
|
181
|
+
|
182
|
+
def rh_merge!(data)
|
183
|
+
_rh_merge(self, data)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Defines structure feature for Array object.
|
188
|
+
class Array
|
189
|
+
private
|
190
|
+
|
191
|
+
# Loop in array
|
192
|
+
def _loop_get_array(sp, key)
|
193
|
+
ret = []
|
194
|
+
each do |e|
|
195
|
+
next unless e.is_a?(Hash)
|
196
|
+
next unless e.key?(key)
|
197
|
+
|
198
|
+
if sp.length == 0
|
199
|
+
ret << e[key]
|
200
|
+
else
|
201
|
+
ret << e[key].rh_get(sp) if [Array, Hash].include?(e[key].class)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
return ret if ret.length > 0
|
205
|
+
nil
|
206
|
+
end
|
207
|
+
|
208
|
+
# Index provided. return the value of the index.
|
209
|
+
def _get_array(sp, key)
|
210
|
+
return self[key] if sp.length == 0
|
211
|
+
|
212
|
+
self[key].rh_get(sp) if [Array, Hash].include?(self[key].class)
|
213
|
+
end
|
214
|
+
|
215
|
+
def _lexist_array(sp, key)
|
216
|
+
return 0 unless key >= 0 && key < length
|
217
|
+
return 1 if sp.length == 0
|
218
|
+
|
219
|
+
1 + self[key].rh_lexist?(sp) if [Array, Hash].include?(self[key].class)
|
220
|
+
end
|
221
|
+
|
222
|
+
def _loop_lexist_array(sp, key)
|
223
|
+
ret = []
|
224
|
+
each do |e|
|
225
|
+
next unless e.is_a?(Hash)
|
226
|
+
next unless e.key?(key)
|
227
|
+
|
228
|
+
if sp.length == 0
|
229
|
+
ret << 1
|
230
|
+
else
|
231
|
+
res = 1
|
232
|
+
res += e[key].rh_lexist?(sp) if [Array, Hash].include?(e[key].class)
|
233
|
+
ret << res
|
234
|
+
end
|
235
|
+
end
|
236
|
+
ret.length > 0 ? ret.max : 0
|
237
|
+
end
|
238
|
+
|
239
|
+
def _keys_match(re, res, sp, opts)
|
240
|
+
empty = false
|
241
|
+
empty = opts.include?('e') if opts
|
242
|
+
|
243
|
+
each do |e|
|
244
|
+
next unless e.is_a?(Hash)
|
245
|
+
|
246
|
+
_keys_match_hash(re, res, sp, e)
|
247
|
+
end
|
248
|
+
return res if empty || res.length > 0
|
249
|
+
nil
|
250
|
+
end
|
251
|
+
|
252
|
+
def _keys_match_hash(re, res, sp, e)
|
253
|
+
e.keys.sort.each do |k|
|
254
|
+
k_re = _key_to_s(k)
|
255
|
+
next unless re.match(k_re)
|
256
|
+
|
257
|
+
if sp.length == 0
|
258
|
+
_update_res(res, k, e[k])
|
259
|
+
else
|
260
|
+
v = e[k].rh_get(sp) if [Array, Hash].include?(e[k].class)
|
261
|
+
|
262
|
+
_update_res(res, k, v) unless v.nil?
|
263
|
+
end
|
264
|
+
end
|
265
|
+
res
|
266
|
+
end
|
267
|
+
|
268
|
+
def _rh_merge(result, data)
|
269
|
+
data = data.clone
|
270
|
+
data_control = _rh_merge_control(data)
|
271
|
+
result_control = _rh_merge_control(result)
|
272
|
+
|
273
|
+
_rh_do_control_merge(result_control, result, data_control, data)
|
274
|
+
|
275
|
+
(1..(data.length - 1)).each do |index|
|
276
|
+
_rh_do_array_merge(result, index, data)
|
277
|
+
end
|
278
|
+
|
279
|
+
(-(result.length - 1)..-1).each do |index|
|
280
|
+
result.delete_at(index.abs) if result[index.abs] == :unset
|
281
|
+
end
|
282
|
+
|
283
|
+
_rh_do_array_merge(result, 0, [data_control])
|
284
|
+
# Remove all control elements in tree of arrays
|
285
|
+
_rh_remove_control(result[0])
|
286
|
+
|
287
|
+
result
|
288
|
+
end
|
289
|
+
|
290
|
+
def _rh_do_array_merge(result, index, data)
|
291
|
+
return if _rh_merge_recursive(result, index, data)
|
292
|
+
|
293
|
+
return unless _rh_struct_changing_ok?(result, index, data)
|
294
|
+
|
295
|
+
return unless _rh_merge_ok?(result, index)
|
296
|
+
|
297
|
+
result[index] = data[index] unless data[index] == :kept
|
298
|
+
end
|
299
|
+
|
300
|
+
# Get the control element. or create it if missing.
|
301
|
+
def _rh_merge_control(array)
|
302
|
+
unless array[0].is_a?(Hash)
|
303
|
+
array.insert(0, :__control => true)
|
304
|
+
return array[0]
|
305
|
+
end
|
306
|
+
|
307
|
+
_rh_control_tags.each do |prop|
|
308
|
+
if array[0].key?(prop)
|
309
|
+
array[0][:__control] = true
|
310
|
+
return array[0]
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
array.insert(0, :__control => true)
|
315
|
+
|
316
|
+
array[0]
|
317
|
+
end
|
318
|
+
|
319
|
+
# Do the merge according to :__add and :__remove
|
320
|
+
def _rh_do_control_merge(_result_control, result, data_control, _data)
|
321
|
+
if data_control[:__remove].is_a?(Array)
|
322
|
+
_rh_do_control_remove(result, data_control[:__remove])
|
323
|
+
elsif data_control[:__remove_index].is_a?(Array)
|
324
|
+
index_to_remove = data_control[:__remove_index].uniq.sort.reverse
|
325
|
+
_rh_do_control_remove_index(result, index_to_remove)
|
326
|
+
end
|
327
|
+
|
328
|
+
data_control.delete(:__remove)
|
329
|
+
data_control.delete(:__remove_index)
|
330
|
+
|
331
|
+
if data_control[:__add].is_a?(Array)
|
332
|
+
data_control[:__add].each { |element| result << element }
|
333
|
+
elsif data_control[:__add_index].is_a?(Hash)
|
334
|
+
_rh_do_control_add_index(result, data_control[:__add_index].sort)
|
335
|
+
end
|
336
|
+
|
337
|
+
data_control.delete(:__add)
|
338
|
+
data_control.delete(:__add_index)
|
339
|
+
end
|
340
|
+
|
341
|
+
def _rh_do_control_add_index(result, add_index)
|
342
|
+
add_index.reverse_each do |elements_to_insert|
|
343
|
+
next unless elements_to_insert.is_a?(Array) &&
|
344
|
+
elements_to_insert[0].is_a?(Fixnum) &&
|
345
|
+
elements_to_insert[1].is_a?(Array)
|
346
|
+
|
347
|
+
index = elements_to_insert[0] + 1
|
348
|
+
elements = elements_to_insert[1]
|
349
|
+
|
350
|
+
elements.reverse_each { |element| result.insert(index, element) }
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
# do the element removal.
|
355
|
+
def _rh_do_control_remove(result, remove)
|
356
|
+
remove.each { |element| result.delete(element) }
|
357
|
+
end
|
358
|
+
|
359
|
+
def _rh_do_control_remove_index(result, index_to_remove)
|
360
|
+
index_to_remove.each { |index| result.delete_at(index + 1) }
|
361
|
+
end
|
362
|
+
|
363
|
+
include Rh
|
364
|
+
include RhGet
|
365
|
+
end
|