hoodie 0.5.5 → 1.0.1
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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile +19 -0
- data/Rakefile +8 -23
- data/hoodie.gemspec +0 -23
- data/lib/hoodie.rb +40 -48
- data/lib/hoodie/configuration.rb +39 -2
- data/lib/hoodie/core_ext/blank.rb +6 -6
- data/lib/hoodie/core_ext/hash.rb +108 -13
- data/lib/hoodie/core_ext/string.rb +5 -3
- data/lib/hoodie/core_ext/try.rb +4 -3
- data/lib/hoodie/inflections.rb +18 -0
- data/lib/hoodie/inflections/defaults.rb +17 -0
- data/lib/hoodie/inflections/inflections.rb +17 -0
- data/lib/hoodie/inflections/rules_collection.rb +17 -0
- data/lib/hoodie/logging.rb +22 -4
- data/lib/hoodie/stash.rb +83 -80
- data/lib/hoodie/stash/disk_store.rb +142 -118
- data/lib/hoodie/stash/mem_store.rb +10 -9
- data/lib/hoodie/stash/memoizable.rb +46 -0
- data/lib/hoodie/utils.rb +13 -183
- data/lib/hoodie/utils/ansi.rb +199 -0
- data/lib/hoodie/utils/crypto.rb +288 -0
- data/lib/hoodie/utils/equalizer.rb +146 -0
- data/lib/hoodie/utils/file_helper.rb +225 -0
- data/lib/hoodie/utils/konstruktor.rb +77 -0
- data/lib/hoodie/utils/machine.rb +83 -0
- data/lib/hoodie/utils/os.rb +56 -0
- data/lib/hoodie/utils/retry.rb +235 -0
- data/lib/hoodie/utils/timeout.rb +54 -0
- data/lib/hoodie/utils/url_helper.rb +104 -0
- data/lib/hoodie/version.rb +4 -4
- metadata +13 -234
- data/lib/hoodie/identity_map.rb +0 -96
- data/lib/hoodie/memoizable.rb +0 -43
- data/lib/hoodie/obfuscate.rb +0 -121
- data/lib/hoodie/observable.rb +0 -309
- data/lib/hoodie/os.rb +0 -43
- data/lib/hoodie/proxy.rb +0 -68
- data/lib/hoodie/rash.rb +0 -125
- data/lib/hoodie/timers.rb +0 -355
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb724e1cb6507df195da226f792105ad37fc4431
|
4
|
+
data.tar.gz: ae69f0b9bad59fbe1b82c891a51d2bd2dcf304c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68e2bfa7b4603de807849eb6ac65f95a256c2b4aad183d5f6390afe99422d306196e47da34914524bdb50c95c646b06ac55ad367277efcbd6efd5bff92370424
|
7
|
+
data.tar.gz: 2349207c4c7ddcf327dc8bafa1e666580b437b3df00b9bf62f71cb79242bf1dac9d731ad833f81cd57bc70ff2e7a028f4b62add255e99577d21a5d305e4360f8
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
# License: Apache License, Version 2.0
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
1
20
|
source 'https://rubygems.org'
|
2
21
|
|
3
22
|
gemspec
|
data/Rakefile
CHANGED
@@ -19,28 +19,13 @@
|
|
19
19
|
|
20
20
|
require 'bundler/gem_tasks'
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
desc 'Build documentation'
|
31
|
-
task doc: [:yard]
|
32
|
-
|
33
|
-
require 'yard'
|
34
|
-
YARD::Config.load_plugin 'redcarpet-ext'
|
35
|
-
YARD::Rake::YardocTask.new do |t|
|
36
|
-
t.files = ['**/*.rb', '-', 'README.md', 'CHANGELOG.md', 'LICENSE']
|
37
|
-
t.options = ['--markup-provider=redcarpet', '--markup=markdown']
|
22
|
+
desc 'Generate Ruby documentation'
|
23
|
+
task :yard do
|
24
|
+
require 'yard'
|
25
|
+
YARD::Rake::YardocTask.new do |t|
|
26
|
+
t.files = ['**/*.rb', '-', 'README.md', 'LICENSE']
|
27
|
+
t.stats_options = %w(--list-undoc)
|
28
|
+
end
|
38
29
|
end
|
39
30
|
|
40
|
-
|
41
|
-
RuboCop::RakeTask.new
|
42
|
-
|
43
|
-
require 'rspec/core/rake_task'
|
44
|
-
RSpec::Core::RakeTask.new(:chefspec) do |t|
|
45
|
-
t.rspec_opts = '--color --format progress'
|
46
|
-
end
|
31
|
+
task doc: %w(yard)
|
data/hoodie.gemspec
CHANGED
@@ -37,33 +37,10 @@ Gem::Specification.new do |gem|
|
|
37
37
|
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
|
38
38
|
gem.extra_rdoc_files = %w[LICENSE README.md]
|
39
39
|
|
40
|
-
gem.add_runtime_dependency 'anemone', '>= 0.7.2'
|
41
|
-
gem.add_runtime_dependency 'hitimes'
|
42
|
-
|
43
40
|
# Development gems
|
44
41
|
gem.add_development_dependency 'rake', '~> 10.4'
|
45
42
|
gem.add_development_dependency 'yard', '~> 0.8'
|
46
43
|
gem.add_development_dependency 'pry'
|
47
|
-
|
48
|
-
# Test gems
|
49
|
-
gem.add_development_dependency 'rspec', '~> 3.2'
|
50
|
-
gem.add_development_dependency 'fuubar', '~> 2.0'
|
51
|
-
gem.add_development_dependency 'simplecov', '~> 0.9'
|
52
44
|
gem.add_development_dependency 'inch'
|
53
45
|
gem.add_development_dependency 'yardstick'
|
54
|
-
gem.add_development_dependency 'guard'
|
55
|
-
gem.add_development_dependency 'guard-shell'
|
56
|
-
gem.add_development_dependency 'guard-yard'
|
57
|
-
gem.add_development_dependency 'guard-rubocop'
|
58
|
-
gem.add_development_dependency 'guard-rspec'
|
59
|
-
gem.add_development_dependency 'ruby_gntp'
|
60
|
-
|
61
|
-
# Integration gems
|
62
|
-
gem.add_development_dependency 'rubocop'
|
63
|
-
gem.add_development_dependency 'geminabox-rake'
|
64
|
-
|
65
|
-
# Versioning
|
66
|
-
gem.add_development_dependency 'version'
|
67
|
-
gem.add_development_dependency 'thor-scmversion'
|
68
|
-
gem.add_development_dependency 'semverse'
|
69
46
|
end
|
data/lib/hoodie.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
|
-
# Author:
|
4
|
-
#
|
5
|
-
# Copyright (C) 2014-2015 Stefano Harding
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
# License: Apache License, Version 2.0
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -17,7 +17,11 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
|
20
|
+
require 'hoodie/core_ext/string'
|
21
|
+
require 'hoodie/core_ext/blank'
|
20
22
|
require 'hoodie/configuration'
|
23
|
+
require 'hoodie/core_ext/hash'
|
24
|
+
require 'hoodie/core_ext/try'
|
21
25
|
|
22
26
|
module Hoodie
|
23
27
|
|
@@ -31,59 +35,47 @@ module Hoodie
|
|
31
35
|
# Raised when an operation times out.
|
32
36
|
TimeoutError = Class.new(StandardError)
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
# @param [Boolean] value
|
39
|
+
# Sets the global logging configuration.
|
40
|
+
#
|
41
|
+
# @return [Hoodie]
|
42
|
+
#
|
43
|
+
def self.logging=(value)
|
44
|
+
configuration.logging = value
|
45
|
+
self
|
46
|
+
end
|
42
47
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
# @return [Boolean]
|
49
|
+
# The global logging setting.
|
50
|
+
#
|
51
|
+
def self.logging
|
52
|
+
configuration.logging
|
53
|
+
end
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
55
|
+
# Provides access to the global configuration.
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# Hoodie.config do |config|
|
59
|
+
# config.logging = true
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# @return [Configuration]
|
63
|
+
#
|
64
|
+
def self.config(&block)
|
65
|
+
yield configuration if block_given?
|
66
|
+
configuration
|
67
|
+
end
|
63
68
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
# @return [Configuration]
|
70
|
+
# The global configuration instance.
|
71
|
+
#
|
72
|
+
def self.configuration
|
73
|
+
@configuration ||= Configuration.new
|
69
74
|
end
|
70
75
|
end
|
71
76
|
|
72
|
-
require 'hoodie/core_ext/string'
|
73
|
-
require 'hoodie/core_ext/blank'
|
74
|
-
require 'hoodie/core_ext/hash'
|
75
|
-
require 'hoodie/core_ext/try'
|
76
|
-
|
77
|
-
require 'hoodie/stash/mem_store'
|
78
|
-
require 'hoodie/stash/disk_store'
|
79
|
-
require 'hoodie/identity_map'
|
80
77
|
require 'hoodie/inflections'
|
81
|
-
require 'hoodie/memoizable'
|
82
|
-
require 'hoodie/obfuscate'
|
83
78
|
require 'hoodie/logging'
|
84
79
|
require 'hoodie/version'
|
85
|
-
require 'hoodie/timers'
|
86
80
|
require 'hoodie/utils'
|
87
|
-
require 'hoodie/proxy'
|
88
81
|
require 'hoodie/stash'
|
89
|
-
require 'hoodie/os'
|
data/lib/hoodie/configuration.rb
CHANGED
@@ -1,14 +1,33 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
# License: Apache License, Version 2.0
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
2
19
|
|
3
20
|
module Hoodie
|
4
21
|
|
5
22
|
# A Configuration instance
|
6
23
|
class Configuration
|
7
24
|
|
8
|
-
#
|
25
|
+
# @!attribute [rw] logging
|
26
|
+
# @return [Boolean] Enable or disable logging.
|
9
27
|
attr_accessor :logging
|
10
28
|
|
11
|
-
#
|
29
|
+
# @!attribute [rw] level
|
30
|
+
# @return [Symbol] Set the desired loging level.
|
12
31
|
attr_accessor :level
|
13
32
|
|
14
33
|
# Initialized a configuration instance
|
@@ -19,10 +38,28 @@ module Hoodie
|
|
19
38
|
def initialize(options={})
|
20
39
|
@logging = options.fetch(:logging, false)
|
21
40
|
@level = options.fetch(:level, :info)
|
41
|
+
@crypto = Crypto::Configuration.new
|
22
42
|
|
23
43
|
yield self if block_given?
|
24
44
|
end
|
25
45
|
|
46
|
+
# Access the crypto for this instance and optional configure a
|
47
|
+
# new crypto with the passed block.
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# Garcon.config do |c|
|
51
|
+
# c.crypto.password = "!mWh0!s@y!m"
|
52
|
+
# c.crypto.salt = "9e5f851900cad8892ac8b737b7370cbe"
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# @return [Crypto]
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
def crypto(&block)
|
59
|
+
@crypto = Crypto::Configuration.new(&block) if block_given?
|
60
|
+
@crypto
|
61
|
+
end
|
62
|
+
|
26
63
|
# @api private
|
27
64
|
def to_h
|
28
65
|
{ logging: logging,
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
|
-
# Author:
|
4
|
-
#
|
5
|
-
# Copyright (C) 2014-2015 Stefano Harding
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
# License: Apache License, Version 2.0
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -25,7 +25,7 @@ class Object
|
|
25
25
|
# [1].blank? #=> false
|
26
26
|
# [nil].blank? #=> false
|
27
27
|
#
|
28
|
-
# @return [
|
28
|
+
# @return [Boolean]
|
29
29
|
#
|
30
30
|
def blank?
|
31
31
|
nil? || (respond_to?(:empty?) && empty?)
|
@@ -37,7 +37,7 @@ class Object
|
|
37
37
|
# [1].present? #=> true
|
38
38
|
# [nil].present? #=> true
|
39
39
|
#
|
40
|
-
# @return [
|
40
|
+
# @return [Boolean]
|
41
41
|
#
|
42
42
|
def present?
|
43
43
|
!blank?
|
@@ -100,7 +100,7 @@ class String
|
|
100
100
|
# " ".blank? #=> true
|
101
101
|
# " hey ho ".blank? #=> false
|
102
102
|
#
|
103
|
-
# @return [
|
103
|
+
# @return [Boolean]
|
104
104
|
#
|
105
105
|
def blank?
|
106
106
|
strip.empty?
|
data/lib/hoodie/core_ext/hash.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
|
-
# Author:
|
4
|
-
#
|
5
|
-
# Copyright (C) 2014-2015 Stefano Harding
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
4
|
+
# License: Apache License, Version 2.0
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
@@ -17,17 +17,69 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
|
20
|
+
|
20
21
|
class Hash
|
22
|
+
|
23
|
+
# Turn a hash into a method arguments.
|
24
|
+
#
|
25
|
+
# h = { :list => [1,2], :base => "HI" }
|
26
|
+
#
|
27
|
+
# Without an argument field.
|
28
|
+
#
|
29
|
+
# h.argumentize #=> [ { :list => [1,2], :base => "HI" } ]
|
30
|
+
#
|
31
|
+
# With an argument field.
|
32
|
+
#
|
33
|
+
# h.argumentize(:list) #=> [ 1, 2, { :base => "HI" } ]
|
34
|
+
# h.argumentize(:base) #=> [ "HI", { :list => [1,2] } ]
|
35
|
+
#
|
36
|
+
def argumentize(args_field = nil)
|
37
|
+
config = dup
|
38
|
+
if args_field
|
39
|
+
args = [config.delete(args_field)].flatten.compact
|
40
|
+
else
|
41
|
+
args = []
|
42
|
+
end
|
43
|
+
args << config
|
44
|
+
return args
|
45
|
+
end
|
46
|
+
|
47
|
+
# A method to convert a Hash into a Struct.
|
48
|
+
#
|
49
|
+
# h = { :name => "Earl", "age" => 20, "sex" => "lots", "worries" => "none" }
|
50
|
+
# s = h.to_struct("Foo")
|
51
|
+
#
|
52
|
+
def to_struct(struct_name)
|
53
|
+
Struct.new(struct_name,*keys).new(*values)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Get or set state of object. You can think of #object_state as an in-code
|
57
|
+
# form of marshalling.
|
58
|
+
#
|
59
|
+
def object_state(data=nil)
|
60
|
+
data ? replace(data) : dup
|
61
|
+
end
|
62
|
+
|
63
|
+
# A hash is blank if it's empty:
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# {}.blank? # => true
|
67
|
+
# { key: 'value' }.blank? # => false
|
68
|
+
#
|
69
|
+
# @api public
|
70
|
+
alias_method :blank?, :empty?
|
71
|
+
|
21
72
|
# Returns a compacted copy (contains no key/value pairs having
|
22
73
|
# nil? values)
|
23
74
|
#
|
24
75
|
# @example
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
76
|
+
# hash = { a: 100, b: nil, c: false, d: '' }
|
77
|
+
# hash.compact # => { a: 100, c: false, d: '' }
|
78
|
+
# hash # => { a: 100, b: nil, c: false, d: '' }
|
28
79
|
#
|
29
80
|
# @return [Hash]
|
30
81
|
#
|
82
|
+
# @api public
|
31
83
|
def compact
|
32
84
|
select { |_, value| !value.nil? }
|
33
85
|
end
|
@@ -35,13 +87,13 @@ class Hash
|
|
35
87
|
# Returns a new hash with all keys converted using the block operation.
|
36
88
|
#
|
37
89
|
# @example
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# # => { "AGE" => "15", "NAME" => "Tiggy" }
|
90
|
+
# hash = { name: 'Tiggy', age: '15' }
|
91
|
+
# hash.transform_keys{ |key| key.to_s.upcase }
|
92
|
+
# # => { "AGE" => "15", "NAME" => "Tiggy" }
|
42
93
|
#
|
43
94
|
# @return [Hash]
|
44
95
|
#
|
96
|
+
# @api public
|
45
97
|
def transform_keys
|
46
98
|
enum_for(:transform_keys) unless block_given?
|
47
99
|
result = self.class.new
|
@@ -128,6 +180,48 @@ class Hash
|
|
128
180
|
recursively_transform_keys { |key| key.to_s.capitalize rescue key }
|
129
181
|
end
|
130
182
|
|
183
|
+
# Creates a new hash from two separate arrays, a +keys+ array and
|
184
|
+
# a +values+ array.
|
185
|
+
#
|
186
|
+
# @example
|
187
|
+
# Hash.zip(['a','b','c'], [1,2,3])
|
188
|
+
# # => { "a"=>1, "b"=>2, "c"=>3 }
|
189
|
+
#
|
190
|
+
def zip(col1, col2)
|
191
|
+
col1.zip(col2).inject({}) { |r, i| r[i[0]] = i[1]; r }
|
192
|
+
end
|
193
|
+
|
194
|
+
# Create a hash with *only* key/value pairs in receiver and +allowed+
|
195
|
+
#
|
196
|
+
# { :one => 1, :two => 2, :three => 3 }.only(:one) # => { :one => 1 }
|
197
|
+
#
|
198
|
+
# @param [Array[String, Symbol]] *allowed The hash keys to include.
|
199
|
+
#
|
200
|
+
# @return [Hash] A new hash with only the selected keys.
|
201
|
+
#
|
202
|
+
# @api public
|
203
|
+
def only(*allowed)
|
204
|
+
hash = {}
|
205
|
+
allowed.each {|k| hash[k] = self[k] if self.has_key?(k) }
|
206
|
+
hash
|
207
|
+
end
|
208
|
+
|
209
|
+
# Create a hash with all key/value pairs in receiver *except* +rejected+
|
210
|
+
#
|
211
|
+
# { :one => 1, :two => 2, :three => 3 }.except(:one)
|
212
|
+
# # => { :two => 2, :three => 3 }
|
213
|
+
#
|
214
|
+
# @param [Array[String, Symbol]] *rejected The hash keys to exclude.
|
215
|
+
#
|
216
|
+
# @return [Hash] A new hash without the selected keys.
|
217
|
+
#
|
218
|
+
# @api public
|
219
|
+
def except(*rejected)
|
220
|
+
hash = self.dup
|
221
|
+
rejected.each {|k| hash.delete(k) }
|
222
|
+
hash
|
223
|
+
end
|
224
|
+
|
131
225
|
class UndefinedPathError < StandardError; end
|
132
226
|
# Recursively searchs a nested datastructure for a key and returns
|
133
227
|
# the value. If a block is provided its value will be returned if
|
@@ -149,7 +243,8 @@ class Hash
|
|
149
243
|
obj.fetch(arg)
|
150
244
|
rescue ArgumentError, IndexError, NoMethodError => e
|
151
245
|
break block.call(arg) if block
|
152
|
-
raise UndefinedPathError,
|
246
|
+
raise UndefinedPathError,
|
247
|
+
"Could not fetch path (#{args.join(' > ')}) at #{arg}", e.backtrace
|
153
248
|
end
|
154
249
|
end
|
155
250
|
end
|
@@ -173,8 +268,8 @@ class Hash
|
|
173
268
|
def _recursively_transform_keys_in_object(object, &block)
|
174
269
|
case object
|
175
270
|
when Hash
|
176
|
-
object.each_with_object({}) do |(key,
|
177
|
-
result[yield(key)] = _recursively_transform_keys_in_object(
|
271
|
+
object.each_with_object({}) do |(key, val), result|
|
272
|
+
result[yield(key)] = _recursively_transform_keys_in_object(val, &block)
|
178
273
|
end
|
179
274
|
when Array
|
180
275
|
object.map { |e| _recursively_transform_keys_in_object(e, &block) }
|