hashie 2.1.2 → 4.1.0

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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +524 -59
  3. data/CONTRIBUTING.md +24 -7
  4. data/README.md +781 -90
  5. data/Rakefile +19 -2
  6. data/UPGRADING.md +245 -0
  7. data/hashie.gemspec +21 -13
  8. data/lib/hashie.rb +60 -21
  9. data/lib/hashie/array.rb +21 -0
  10. data/lib/hashie/clash.rb +24 -12
  11. data/lib/hashie/dash.rb +96 -33
  12. data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
  13. data/lib/hashie/extensions/array/pretty_inspect.rb +19 -0
  14. data/lib/hashie/extensions/coercion.rb +124 -18
  15. data/lib/hashie/extensions/dash/coercion.rb +25 -0
  16. data/lib/hashie/extensions/dash/indifferent_access.rb +56 -0
  17. data/lib/hashie/extensions/dash/property_translation.rb +191 -0
  18. data/lib/hashie/extensions/deep_fetch.rb +7 -5
  19. data/lib/hashie/extensions/deep_find.rb +69 -0
  20. data/lib/hashie/extensions/deep_locate.rb +113 -0
  21. data/lib/hashie/extensions/deep_merge.rb +35 -12
  22. data/lib/hashie/extensions/ignore_undeclared.rb +11 -5
  23. data/lib/hashie/extensions/indifferent_access.rb +28 -16
  24. data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
  25. data/lib/hashie/extensions/key_conversion.rb +0 -82
  26. data/lib/hashie/extensions/mash/define_accessors.rb +90 -0
  27. data/lib/hashie/extensions/mash/keep_original_keys.rb +53 -0
  28. data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
  29. data/lib/hashie/extensions/mash/safe_assignment.rb +18 -0
  30. data/lib/hashie/extensions/mash/symbolize_keys.rb +38 -0
  31. data/lib/hashie/extensions/method_access.rb +154 -11
  32. data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +48 -0
  33. data/lib/hashie/extensions/pretty_inspect.rb +19 -0
  34. data/lib/hashie/extensions/ruby_version.rb +60 -0
  35. data/lib/hashie/extensions/ruby_version_check.rb +21 -0
  36. data/lib/hashie/extensions/strict_key_access.rb +77 -0
  37. data/lib/hashie/extensions/stringify_keys.rb +71 -0
  38. data/lib/hashie/extensions/symbolize_keys.rb +71 -0
  39. data/lib/hashie/hash.rb +27 -8
  40. data/lib/hashie/logger.rb +18 -0
  41. data/lib/hashie/mash.rb +235 -57
  42. data/lib/hashie/railtie.rb +21 -0
  43. data/lib/hashie/rash.rb +40 -16
  44. data/lib/hashie/trash.rb +2 -88
  45. data/lib/hashie/utils.rb +44 -0
  46. data/lib/hashie/version.rb +1 -1
  47. metadata +42 -81
  48. data/.gitignore +0 -9
  49. data/.rspec +0 -2
  50. data/.rubocop.yml +0 -36
  51. data/.travis.yml +0 -15
  52. data/Gemfile +0 -11
  53. data/Guardfile +0 -5
  54. data/lib/hashie/hash_extensions.rb +0 -47
  55. data/spec/hashie/clash_spec.rb +0 -48
  56. data/spec/hashie/dash_spec.rb +0 -338
  57. data/spec/hashie/extensions/coercion_spec.rb +0 -156
  58. data/spec/hashie/extensions/deep_fetch_spec.rb +0 -70
  59. data/spec/hashie/extensions/deep_merge_spec.rb +0 -22
  60. data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -23
  61. data/spec/hashie/extensions/indifferent_access_spec.rb +0 -152
  62. data/spec/hashie/extensions/key_conversion_spec.rb +0 -103
  63. data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
  64. data/spec/hashie/extensions/method_access_spec.rb +0 -121
  65. data/spec/hashie/hash_spec.rb +0 -66
  66. data/spec/hashie/mash_spec.rb +0 -467
  67. data/spec/hashie/rash_spec.rb +0 -44
  68. data/spec/hashie/trash_spec.rb +0 -193
  69. data/spec/hashie/version_spec.rb +0 -7
  70. data/spec/spec.opts +0 -3
  71. data/spec/spec_helper.rb +0 -8
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'rails/railtie'
3
+
4
+ module Hashie
5
+ class Railtie < Rails::Railtie
6
+ # Set the Hashie.logger to use Rails.logger when used with rails.
7
+ initializer 'hashie.configure_logger', after: 'initialize_logger' do
8
+ Hashie.logger = Rails.logger
9
+ end
10
+
11
+ initializer 'hashie.patch_hash_except', after: 'load_active_support' do
12
+ if Rails::VERSION::MAJOR >= 6
13
+ require 'hashie/extensions/active_support/core_ext/hash'
14
+ Hashie::Mash.send(:include, Hashie::Extensions::ActiveSupport::CoreExt::Hash)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ rescue LoadError => e
20
+ Hashie.logger.info("Hashie skipping railtie as #{e.message}")
21
+ end
@@ -60,6 +60,28 @@ module Hashie
60
60
  all(key).first
61
61
  end
62
62
 
63
+ #
64
+ # Raise (or yield) unless something matches the key.
65
+ #
66
+ def fetch(*args)
67
+ raise ArgumentError, "Expected 1-2 arguments, got #{args.length}" \
68
+ unless (1..2).cover?(args.length)
69
+
70
+ key, default = args
71
+
72
+ all(key) do |value|
73
+ return value
74
+ end
75
+
76
+ if block_given?
77
+ yield key
78
+ elsif default
79
+ default
80
+ else
81
+ raise KeyError, "key not found: #{key.inspect}"
82
+ end
83
+ end
84
+
63
85
  #
64
86
  # Return everything that matches the query.
65
87
  #
@@ -78,25 +100,24 @@ module Hashie
78
100
  # see if any of the regexps match the string
79
101
  @regexes.each do |regex|
80
102
  match = regex.match(query)
81
- if match
82
- @regex_counts[regex] += 1
83
- value = @hash[regex]
84
- if value.respond_to? :call
85
- yield value.call(match)
86
- else
87
- yield value
88
- end
103
+ next unless match
104
+ @regex_counts[regex] += 1
105
+ value = @hash[regex]
106
+ if value.respond_to? :call
107
+ yield value.call(match)
108
+ else
109
+ yield value
89
110
  end
90
111
  end
91
112
 
92
- when Integer
113
+ when Numeric
93
114
  # see if any of the ranges match the integer
94
115
  @ranges.each do |range|
95
- yield @hash[range] if range.include? query
116
+ yield @hash[range] if range.cover? query
96
117
  end
97
118
 
98
119
  when Regexp
99
- # Reverse operation: `rash[/regexp/]` returns all the hash's string keys which match the regexp
120
+ # Reverse operation: `rash[/regexp/]` returns all string keys matching the regexp
100
121
  @hash.each do |key, val|
101
122
  yield val if key.is_a?(String) && query =~ key
102
123
  end
@@ -104,16 +125,19 @@ module Hashie
104
125
  end
105
126
 
106
127
  def method_missing(*args, &block)
107
- @hash.send(*args, &block)
128
+ @hash.send(*args, &block) || super
129
+ end
130
+
131
+ def respond_to_missing?(method_name, _include_private = false)
132
+ @hash.respond_to?(method_name)
108
133
  end
109
134
 
110
135
  private
111
136
 
112
137
  def optimize_if_necessary!
113
- if (@lookups += 1) >= @optimize_every
114
- @regexes = @regex_counts.sort_by { |regex, count| -count }.map { |regex, count| regex }
115
- @lookups = 0
116
- end
138
+ return unless (@lookups += 1) >= @optimize_every
139
+ @regexes = @regexes.sort_by { |regex| -@regex_counts[regex] }
140
+ @lookups = 0
117
141
  end
118
142
  end
119
143
  end
@@ -1,4 +1,5 @@
1
1
  require 'hashie/dash'
2
+ require 'hashie/extensions/dash/property_translation'
2
3
 
3
4
  module Hashie
4
5
  # A Trash is a 'translated' Dash where the keys can be remapped from a source
@@ -8,93 +9,6 @@ module Hashie
8
9
  # such as a Java api, where the keys are named differently from how we would
9
10
  # in Ruby.
10
11
  class Trash < Dash
11
- # Defines a property on the Trash. Options are as follows:
12
- #
13
- # * <tt>:default</tt> - Specify a default value for this property, to be
14
- # returned before a value is set on the property in a new Dash.
15
- # * <tt>:from</tt> - Specify the original key name that will be write only.
16
- # * <tt>:with</tt> - Specify a lambda to be used to convert value.
17
- # * <tt>:transform_with</tt> - Specify a lambda to be used to convert value
18
- # without using the :from option. It transform the property itself.
19
- def self.property(property_name, options = {})
20
- super
21
-
22
- options[:from] = options[:from].to_sym if options[:from]
23
- property_name = property_name.to_sym
24
-
25
- if options[:from]
26
- if property_name == options[:from]
27
- fail ArgumentError, "Property name (#{property_name}) and :from option must not be the same"
28
- end
29
-
30
- translations[options[:from].to_sym] = property_name.to_sym
31
-
32
- define_method "#{options[:from]}=" do |val|
33
- with = options[:with] || options[:transform_with]
34
- self[property_name.to_sym] = with.respond_to?(:call) ? with.call(val) : val
35
- end
36
- else
37
- if options[:transform_with].respond_to? :call
38
- transforms[property_name.to_sym] = options[:transform_with]
39
- end
40
- end
41
- end
42
-
43
- # Set a value on the Dash in a Hash-like way. Only works
44
- # on pre-existing properties.
45
- def []=(property, value)
46
- if self.class.translations.key? property.to_sym
47
- send("#{property}=", value)
48
- elsif self.class.transforms.key? property.to_sym
49
- super property, self.class.transforms[property.to_sym].call(value)
50
- elsif property_exists? property
51
- super
52
- end
53
- end
54
-
55
- def self.permitted_input_keys
56
- @permitted_input_keys ||= properties.map { |property| inverse_translations.fetch property, property }
57
- end
58
-
59
- private
60
-
61
- def self.properties
62
- @properties ||= []
63
- end
64
-
65
- def self.translations
66
- @translations ||= {}
67
- end
68
-
69
- def self.inverse_translations
70
- @inverse_translations ||= Hash[translations.map(&:reverse)]
71
- end
72
-
73
- def self.transforms
74
- @transforms ||= {}
75
- end
76
-
77
- # Raises an NoMethodError if the property doesn't exist
78
- #
79
- def property_exists?(property)
80
- unless self.class.property?(property.to_sym)
81
- fail NoMethodError, "The property '#{property}' is not defined for this Trash."
82
- end
83
- true
84
- end
85
-
86
- private
87
-
88
- # Deletes any keys that have a translation
89
- def initialize_attributes(attributes)
90
- return unless attributes
91
- attributes_copy = attributes.dup.delete_if do |k, v|
92
- if self.class.translations.include?(k.to_sym)
93
- self[k] = v
94
- true
95
- end
96
- end
97
- super attributes_copy
98
- end
12
+ include Hashie::Extensions::Dash::PropertyTranslation
99
13
  end
100
14
  end
@@ -0,0 +1,44 @@
1
+ module Hashie
2
+ # A collection of helper methods that can be used throughout the gem.
3
+ module Utils
4
+ # Describes a method by where it was defined.
5
+ #
6
+ # @param bound_method [Method] The method to describe.
7
+ # @return [String]
8
+ def self.method_information(bound_method)
9
+ if bound_method.source_location
10
+ "defined at #{bound_method.source_location.join(':')}"
11
+ else
12
+ "defined in #{bound_method.owner}"
13
+ end
14
+ end
15
+
16
+ # Duplicates a value or returns the value when it is not duplicable
17
+ #
18
+ # @api public
19
+ #
20
+ # @param value [Object] the value to safely duplicate
21
+ # @return [Object] the duplicated value
22
+ def self.safe_dup(value)
23
+ case value
24
+ when Complex, FalseClass, NilClass, Rational, Method, Symbol, TrueClass, *integer_classes
25
+ value
26
+ else
27
+ value.dup
28
+ end
29
+ end
30
+
31
+ # Lists the classes Ruby uses for integers
32
+ #
33
+ # @api private
34
+ # @return [Array<Class>]
35
+ def self.integer_classes
36
+ @integer_classes ||=
37
+ if 0.class == Integer
38
+ [Integer]
39
+ else
40
+ [Fixnum, Bignum] # rubocop:disable Lint/UnifiedInteger
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module Hashie
2
- VERSION = '2.1.2'
2
+ VERSION = '4.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashie
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
5
- prerelease:
4
+ version: 4.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Michael Bleigh
@@ -10,38 +9,20 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-06-12 00:00:00.000000000 Z
12
+ date: 2020-02-01 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
- name: rake
15
+ name: bundler
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - ">="
21
19
  - !ruby/object:Gem::Version
22
20
  version: '0'
23
21
  type: :development
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
29
- - !ruby/object:Gem::Version
30
- version: '0'
31
- - !ruby/object:Gem::Dependency
32
- name: rspec
33
- requirement: !ruby/object:Gem::Requirement
34
- none: false
35
- requirements:
36
- - - ! '>='
37
- - !ruby/object:Gem::Version
38
- version: '0'
39
- type: :development
40
- prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
- requirements:
44
- - - ! '>='
25
+ - - ">="
45
26
  - !ruby/object:Gem::Version
46
27
  version: '0'
47
28
  description: Hashie is a collection of classes and mixins that make hashes more powerful.
@@ -52,99 +33,79 @@ executables: []
52
33
  extensions: []
53
34
  extra_rdoc_files: []
54
35
  files:
55
- - .gitignore
56
- - .rspec
57
- - .rubocop.yml
58
- - .travis.yml
59
- - .yardopts
36
+ - ".yardopts"
60
37
  - CHANGELOG.md
61
38
  - CONTRIBUTING.md
62
- - Gemfile
63
- - Guardfile
64
39
  - LICENSE
65
40
  - README.md
66
41
  - Rakefile
42
+ - UPGRADING.md
67
43
  - hashie.gemspec
68
44
  - lib/hashie.rb
45
+ - lib/hashie/array.rb
69
46
  - lib/hashie/clash.rb
70
47
  - lib/hashie/dash.rb
48
+ - lib/hashie/extensions/active_support/core_ext/hash.rb
49
+ - lib/hashie/extensions/array/pretty_inspect.rb
71
50
  - lib/hashie/extensions/coercion.rb
51
+ - lib/hashie/extensions/dash/coercion.rb
52
+ - lib/hashie/extensions/dash/indifferent_access.rb
53
+ - lib/hashie/extensions/dash/property_translation.rb
72
54
  - lib/hashie/extensions/deep_fetch.rb
55
+ - lib/hashie/extensions/deep_find.rb
56
+ - lib/hashie/extensions/deep_locate.rb
73
57
  - lib/hashie/extensions/deep_merge.rb
74
58
  - lib/hashie/extensions/ignore_undeclared.rb
75
59
  - lib/hashie/extensions/indifferent_access.rb
60
+ - lib/hashie/extensions/key_conflict_warning.rb
76
61
  - lib/hashie/extensions/key_conversion.rb
62
+ - lib/hashie/extensions/mash/define_accessors.rb
63
+ - lib/hashie/extensions/mash/keep_original_keys.rb
64
+ - lib/hashie/extensions/mash/permissive_respond_to.rb
65
+ - lib/hashie/extensions/mash/safe_assignment.rb
66
+ - lib/hashie/extensions/mash/symbolize_keys.rb
77
67
  - lib/hashie/extensions/merge_initializer.rb
78
68
  - lib/hashie/extensions/method_access.rb
69
+ - lib/hashie/extensions/parsers/yaml_erb_parser.rb
70
+ - lib/hashie/extensions/pretty_inspect.rb
71
+ - lib/hashie/extensions/ruby_version.rb
72
+ - lib/hashie/extensions/ruby_version_check.rb
73
+ - lib/hashie/extensions/strict_key_access.rb
74
+ - lib/hashie/extensions/stringify_keys.rb
75
+ - lib/hashie/extensions/symbolize_keys.rb
79
76
  - lib/hashie/hash.rb
80
- - lib/hashie/hash_extensions.rb
77
+ - lib/hashie/logger.rb
81
78
  - lib/hashie/mash.rb
79
+ - lib/hashie/railtie.rb
82
80
  - lib/hashie/rash.rb
83
81
  - lib/hashie/trash.rb
82
+ - lib/hashie/utils.rb
84
83
  - lib/hashie/version.rb
85
- - spec/hashie/clash_spec.rb
86
- - spec/hashie/dash_spec.rb
87
- - spec/hashie/extensions/coercion_spec.rb
88
- - spec/hashie/extensions/deep_fetch_spec.rb
89
- - spec/hashie/extensions/deep_merge_spec.rb
90
- - spec/hashie/extensions/ignore_undeclared_spec.rb
91
- - spec/hashie/extensions/indifferent_access_spec.rb
92
- - spec/hashie/extensions/key_conversion_spec.rb
93
- - spec/hashie/extensions/merge_initializer_spec.rb
94
- - spec/hashie/extensions/method_access_spec.rb
95
- - spec/hashie/hash_spec.rb
96
- - spec/hashie/mash_spec.rb
97
- - spec/hashie/rash_spec.rb
98
- - spec/hashie/trash_spec.rb
99
- - spec/hashie/version_spec.rb
100
- - spec/spec.opts
101
- - spec/spec_helper.rb
102
- homepage: https://github.com/intridea/hashie
84
+ homepage: https://github.com/hashie/hashie
103
85
  licenses:
104
86
  - MIT
87
+ metadata:
88
+ bug_tracker_uri: https://github.com/hashie/hashie/issues
89
+ changelog_uri: https://github.com/hashie/hashie/blob/master/CHANGELOG.md
90
+ documentation_uri: https://www.rubydoc.info/gems/hashie
91
+ source_code_uri: https://github.com/hashie/hashie
105
92
  post_install_message:
106
93
  rdoc_options: []
107
94
  require_paths:
108
95
  - lib
109
96
  required_ruby_version: !ruby/object:Gem::Requirement
110
- none: false
111
97
  requirements:
112
- - - ! '>='
98
+ - - ">="
113
99
  - !ruby/object:Gem::Version
114
100
  version: '0'
115
- segments:
116
- - 0
117
- hash: 775336832915500848
118
101
  required_rubygems_version: !ruby/object:Gem::Requirement
119
- none: false
120
102
  requirements:
121
- - - ! '>='
103
+ - - ">="
122
104
  - !ruby/object:Gem::Version
123
105
  version: '0'
124
- segments:
125
- - 0
126
- hash: 775336832915500848
127
106
  requirements: []
128
- rubyforge_project:
129
- rubygems_version: 1.8.25
107
+ rubygems_version: 3.0.3
130
108
  signing_key:
131
- specification_version: 3
109
+ specification_version: 4
132
110
  summary: Your friendly neighborhood hash library.
133
- test_files:
134
- - spec/hashie/clash_spec.rb
135
- - spec/hashie/dash_spec.rb
136
- - spec/hashie/extensions/coercion_spec.rb
137
- - spec/hashie/extensions/deep_fetch_spec.rb
138
- - spec/hashie/extensions/deep_merge_spec.rb
139
- - spec/hashie/extensions/ignore_undeclared_spec.rb
140
- - spec/hashie/extensions/indifferent_access_spec.rb
141
- - spec/hashie/extensions/key_conversion_spec.rb
142
- - spec/hashie/extensions/merge_initializer_spec.rb
143
- - spec/hashie/extensions/method_access_spec.rb
144
- - spec/hashie/hash_spec.rb
145
- - spec/hashie/mash_spec.rb
146
- - spec/hashie/rash_spec.rb
147
- - spec/hashie/trash_spec.rb
148
- - spec/hashie/version_spec.rb
149
- - spec/spec.opts
150
- - spec/spec_helper.rb
111
+ test_files: []