hashie 3.2.0 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9392e6b092e218e8f232ce4232ffc42e593321d8
4
- data.tar.gz: 96d123ecbe640bf034bd43108e27da8d437d9720
3
+ metadata.gz: 6551cd1a2b88f91c4e0517a95835202ca6b44152
4
+ data.tar.gz: cb7b3ebb5a7dae20e11489b1a393a88ddad1add0
5
5
  SHA512:
6
- metadata.gz: 13c30a48d328a2427cfe2325f0690e2621fcf601bc0354b5d0831f005e4c23ea4fc83b40aef250ce85b9c4434fe6733cff2b5be2822f313b9535485e7003eef6
7
- data.tar.gz: e03895318b6f26ac05e394069c30eb9eb8a98f86b206996f04a19402dd2c283ad2cd52f203e739b7a2b30f7ae4282840a6be783ea8f21cf550e047d2ed732129
6
+ metadata.gz: dfb86431453dbd01e46a71267457ba218e6fbf718bf6f3b246ed420a97db853ab1bed1c9db0a9491cc5a19aff54f8ec7be8a5262fa5360cfec29da63549644e1
7
+ data.tar.gz: fd8047680fcde393057b48f6cf9147bedc41a0e9d2824be3a28a1de8b3d962091cb343c2b32d6e5a47ac88b93b324ca16a89eecfc094aae5744ba8e715dbf75f
data/.rubocop.yml CHANGED
@@ -1,36 +1,34 @@
1
1
  AllCops:
2
2
  Exclude:
3
- - vendor/**
4
- - bin/**
5
3
  - .bundle/**
4
+ - bin/**
5
+ - vendor/**
6
6
 
7
- LineLength:
8
- Enabled: false
9
-
10
- MethodLength:
7
+ Style/CaseEquality:
11
8
  Enabled: false
12
9
 
13
- ClassLength:
10
+ Style/Documentation:
11
+ # don't require classes to be documented
14
12
  Enabled: false
15
13
 
16
- Documentation:
17
- # don't require classes to be documented
14
+ Style/DoubleNegation:
18
15
  Enabled: false
19
16
 
20
- Encoding:
17
+ Style/Encoding:
21
18
  # no need to always specify encoding
22
19
  Enabled: false
23
20
 
24
- Lambda:
25
- # TODO: replace all lambda with -> or Proc
21
+ Metrics/ClassLength:
26
22
  Enabled: false
27
23
 
28
- CyclomaticComplexity:
24
+ Metrics/CyclomaticComplexity:
29
25
  Enabled: false
30
26
 
31
- DoubleNegation:
27
+ Metrics/LineLength:
32
28
  Enabled: false
33
29
 
34
- CaseEquality:
30
+ Metrics/MethodLength:
35
31
  Enabled: false
36
32
 
33
+ Metrics/PerceivedComplexity:
34
+ Max: 10
data/.travis.yml CHANGED
@@ -1,14 +1,14 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - ruby-head
5
4
  - 2.1.2
6
5
  - 2.1.0
7
6
  - 2.0.0
8
7
  - 1.9.3
9
8
  - jruby-19mode
9
+ - rbx-2.2.10
10
10
  - jruby-head
11
- - rbx-2
11
+ - ruby-head
12
12
 
13
13
  matrix:
14
14
  allow_failures:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## Next Release
2
+
3
+ * Your contribution here.
4
+
5
+ ## 3.3.1 (8/26/2014)
6
+
7
+ * [#183](https://github.com/intridea/hashie/pull/183): Added Mash#load with YAML file support - [@gregory](https://github.com/gregory).
8
+ * [#195](https://github.com/intridea/hashie/pull/195): Ensure that the same object is returned after injecting IndifferentAccess - [@michaelherold](https://github.com/michaelherold).
9
+ * [#201](https://github.com/intridea/hashie/pull/201): Hashie::Trash transforms can be inherited - [@fobocaster](https://github.com/fobocaster).
10
+ * [#189](https://github.com/intridea/hashie/pull/189): Added Rash#fetch - [@medcat](https://github.com/medcat).
11
+ * [#200](https://github.com/intridea/hashie/pull/200): Improved coercion: primitives and error handling - [@maxlinc](https://github.com/maxlinc).
12
+ * [#204](https://github.com/intridea/hashie/pull/204): Added Hashie::Extensions::MethodOverridingWriter and Hashie::Extensions::MethodAccessWithOverride - [@michaelherold](https://github.com/michaelherold).
13
+ * [#205](http://github.com/intridea/hashie/pull/205): Added Hashie::Extensions::Mash::SafeAssignment - [@michaelherold](https://github.com/michaelherold).
14
+ * [#206](http://github.com/intridea/hashie/pull/206): Fixed stack overflow from repetitively including coercion in subclasses - [@michaelherold](https://github.com/michaelherold).
15
+ * [#207](http://github.com/intridea/hashie/pull/207): Fixed inheritance of transformations in Trash - [@fobocaster](https://github.com/fobocaster).
16
+ * [#209](http://github.com/intridea/hashie/pull/209): Added Hashie::Extensions::DeepFind - [@michaelherold](https://github.com/michaelherold).
17
+ * [#69](https://github.com/intridea/hashie/pull/69): Fixed regression in assigning multiple properties in Hashie::Trash - [@michaelherold](https://github.com/michaelherold), [@einzige](https://github.com/einzige), [@dblock](https://github.com/dblock).
18
+
1
19
  ## 3.2.0 (7/10/2014)
2
20
 
3
21
  * [#164](https://github.com/intridea/hashie/pull/164), [#165](https://github.com/intridea/hashie/pull/165), [#166](https://github.com/intridea/hashie/pull/166): Fixed stack overflow when coercing mashes that contain ActiveSupport::HashWithIndifferentAccess values - [@numinit](https://github.com/numinit), [@kgrz](https://github.com/kgrz).
data/Gemfile CHANGED
@@ -6,9 +6,17 @@ platforms :rbx do
6
6
  gem 'racc'
7
7
  end
8
8
 
9
- gemspec
9
+ group :development do
10
+ gem 'pry'
11
+ gem 'pry-stack_explorer', platforms: [:ruby_19, :ruby_20, :ruby_21]
12
+ gem 'rubocop', '~> 0.25'
13
+ gem 'guard', '~> 2.6.1'
14
+ gem 'guard-rspec', '~> 4.3.1', require: false
15
+ end
10
16
 
11
- gem 'rubocop', '0.24.1'
17
+ gemspec
12
18
 
13
- # ActiveSupport required to test compatibility with ActiveSupport Core Extensions.
14
- gem 'activesupport', require: false
19
+ group :test do
20
+ # ActiveSupport required to test compatibility with ActiveSupport Core Extensions.
21
+ gem 'activesupport', require: false
22
+ end
data/Guardfile CHANGED
@@ -1,5 +1,5 @@
1
- guard 'rspec' do
2
- watch(%r{^spec/.+_spec\.rb})
3
- watch(%r{^lib/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
4
- watch('spec/spec_helper.rb') { "spec" }
1
+ guard 'rspec', all_on_start: false, cmd: 'bundle exec rspec' do
2
+ watch(/^spec\/.+_spec\.rb/)
3
+ watch(/^lib\/(.+)\.rb/) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { 'spec' }
5
5
  end
data/README.md CHANGED
@@ -12,7 +12,7 @@ $ gem install hashie
12
12
 
13
13
  ## Upgrading
14
14
 
15
- You're reading the documentation for the stable release of Hashie, 3.2.0. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
15
+ You're reading the documentation for the next release of Hashie, which should be 3.3.2. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version. The current stable release is [3.3.1](https://github.com/intridea/hashie/blob/v3.3.1/README.md).
16
16
 
17
17
  ## Hash Extensions
18
18
 
@@ -96,6 +96,47 @@ tweet.relations.class # => Hash
96
96
  # and Relation.new on each value since Relation doesn't define the `coerce` class method
97
97
  ```
98
98
 
99
+ ### Coercing Core Types
100
+
101
+ Hashie handles coercion to the following by using standard conversion methods:
102
+
103
+ | type | method |
104
+ |----------|----------|
105
+ | Integer | `#to_i` |
106
+ | Float | `#to_f` |
107
+ | Complex | `#to_c` |
108
+ | Rational | `#to_r` |
109
+ | String | `#to_s` |
110
+ | Symbol | `#to_sym`|
111
+
112
+ **Note**: The standard Ruby conversion methods are less strict than you may assume. For example, `:foo.to_i` raises an error but `"foo".to_i` returns 0.
113
+
114
+ You can also use coerce from the following supertypes with `coerce_value`:
115
+ - Integer
116
+ - Numeric
117
+
118
+ Hashie does not have built-in support for coercion boolean values, since Ruby does not have a built-in boolean type or standard method for to a boolean. You can coerce to booleans using a custom proc.
119
+
120
+ ### Coercion Proc
121
+
122
+ You can use a custom coercion proc on either `#coerce_key` or `#coerce_value`. This is useful for coercing to booleans or other simple types without creating a new class and `coerce` method. For example:
123
+
124
+ ```ruby
125
+ class Tweet < Hash
126
+ include Hashie::Extensions::Coercion
127
+ coerce_key :retweeted, ->(v) do
128
+ case v
129
+ when String
130
+ return !!(v =~ /^(true|t|yes|y|1)$/i)
131
+ when Numeric
132
+ return !v.to_i.zero?
133
+ else
134
+ return v == true
135
+ end
136
+ end
137
+ end
138
+ ```
139
+
99
140
  ### KeyConversion
100
141
 
101
142
  The KeyConversion extension gives you the convenience methods of `symbolize_keys` and `stringify_keys` along with their bang counterparts. You can also include just stringify or just symbolize with `Hashie::Extensions::StringifyKeys` or `Hashie::Extensions::SymbolizeKeys`.
@@ -119,6 +160,29 @@ h.abc # => 'def'
119
160
  h.abc? # => true
120
161
  ```
121
162
 
163
+ ### MethodAccessWithOverride
164
+
165
+ The MethodAccessWithOverride extension is like the MethodAccess extension, except that it allows you to override Hash methods. It aliases any overridden method with two leading underscores. To include only this overriding functionality, you can include the single module `Hashie::Extensions::MethodOverridingWriter`.
166
+
167
+ ```ruby
168
+ class MyHash < Hash
169
+ include Hashie::Extensions::MethodAccess
170
+ end
171
+
172
+ class MyOverridingHash < Hash
173
+ include Hashie::Extensions::MethodAccessWithOverride
174
+ end
175
+
176
+ non_overriding = MyHash.new
177
+ non_overriding.zip = 'a-dee-doo-dah'
178
+ non_overriding.zip #=> [[['zip', 'a-dee-doo-dah']]]
179
+
180
+ overriding = MyHash.new
181
+ overriding.zip = 'a-dee-doo-dah'
182
+ overriding.zip #=> 'a-dee-doo-dah'
183
+ overriding.__zip #=> [[['zip', 'a-dee-doo-dah']]]
184
+ ```
185
+
122
186
  ### IndifferentAccess
123
187
 
124
188
  This extension can be mixed in to instantly give you indifferent access to your Hash subclass. This works just like the params hash in Rails and other frameworks where whether you provide symbols or strings to access keys, you will get the same results.
@@ -196,9 +260,35 @@ user.deep_fetch :name, :middle { |key| 'default' } # => 'default'
196
260
  user.deep_fetch :groups, 1, :name # => 'Open source enthusiasts'
197
261
  ```
198
262
 
263
+ ### DeepFind
264
+
265
+ This extension can be mixed in to provide for concise searching for keys within a deeply nested hash.
266
+
267
+ It can also search through any Enumerable contained within the hash for objects with the specified key.
268
+
269
+ Note: The searches are depth-first, so it is not guaranteed that a shallowly nested value will be found before a deeply nested value.
270
+
271
+ ```ruby
272
+ user = {
273
+ name: { first: 'Bob', last: 'Boberts' },
274
+ groups: [
275
+ { name: 'Rubyists' },
276
+ { name: 'Open source enthusiasts' }
277
+ ]
278
+ }
279
+
280
+ user.extend Hashie::Extensions::DeepFind
281
+
282
+ user.deep_find(:name) #=> { first: 'Bob', last: 'Boberts' }
283
+ user.deep_detect(:name) #=> { first: 'Bob', last: 'Boberts' }
284
+
285
+ user.deep_find_all(:name) #=> [{ first: 'Bob', last: 'Boberts' }, 'Rubyists', 'Open source enthusiasts']
286
+ user.deep_select(:name) #=> [{ first: 'Bob', last: 'Boberts' }, 'Rubyists', 'Open source enthusiasts']
287
+ ```
288
+
199
289
  ## Mash
200
290
 
201
- Mash is an extended Hash that gives simple pseudo-object functionality that can be built from hashes and easily extended. It is designed to be used in RESTful API libraries to provide easy object-like access to JSON and XML parsed hashes.
291
+ Mash is an extended Hash that gives simple pseudo-object functionality that can be built from hashes and easily extended. It is intended to give the user easier access to the objects within the Mash through a property-like syntax, while still retaining all Hash functionality.
202
292
 
203
293
  ### Example:
204
294
 
@@ -224,6 +314,75 @@ mash.inspect # => <Hashie::Mash>
224
314
 
225
315
  **Note:** The `?` method will return false if a key has been set to false or nil. In order to check if a key has been set at all, use the `mash.key?('some_key')` method instead.
226
316
 
317
+ Please note that a Mash will not override methods through the use of the property-like syntax. This can lead to confusion if you expect to be able to access a Mash value through the property-like syntax for a key that conflicts with a method name. However, it protects users of your library from the unexpected behavior of those methods being overridden behind the scenes.
318
+
319
+ ### Example:
320
+
321
+ ```ruby
322
+ mash = Hashie::Mash.new
323
+ mash.name = "My Mash"
324
+ mash.zip = "Method Override?"
325
+ mash.zip # => [[["name", "My Mash"]], [["zip", "Method Override?"]]]
326
+ ```
327
+
328
+ Mash allows you also to transform any files into a Mash objects.
329
+
330
+ ### Example:
331
+
332
+ ```yml
333
+ #/etc/config/settings/twitter.yml
334
+ development:
335
+ api_key: 'api_key'
336
+ production:
337
+ api_key: <%= ENV['API_KEY'] %> #let's say that ENV['API_KEY'] is set to 'abcd'
338
+ ```
339
+
340
+ ```ruby
341
+ mash = Mash.load('settings/twitter.yml')
342
+ mash.development.api_key # => 'localhost'
343
+ mash.development.api_key = "foo" # => <# RuntimeError can't modify frozen ...>
344
+ mash.development.api_key? # => true
345
+ ```
346
+
347
+ You can access a Mash from another class:
348
+
349
+ ```ruby
350
+ mash = Mash.load('settings/twitter.yml')[ENV['RACK_ENV']]
351
+ Twitter.extend mash.to_module # NOTE: if you want another name than settings, call: to_module('my_settings')
352
+ Twitter.settings.api_key # => 'abcd'
353
+ ```
354
+
355
+ You can use another parser (by default: YamlErbParser):
356
+
357
+ ```
358
+ #/etc/data/user.csv
359
+ id | name | lastname
360
+ ---|------------- | -------------
361
+ 1 |John | Doe
362
+ 2 |Laurent | Garnier
363
+ ```
364
+
365
+ ```ruby
366
+ mash = Mash.load('data/user.csv', parser: MyCustomCsvParser)
367
+ # => { 1 => { name: 'John', lastname: 'Doe'}, 2 => { name: 'Laurent', lastname: 'Garnier' } }
368
+ mash[1] #=> { name: 'John', lastname: 'Doe' }
369
+ ```
370
+
371
+ ### Mash Extension: SafeAssignment
372
+
373
+ This extension can be mixed into a Mash to guard the attempted overwriting of methods by property setters. When mixed in, the Mash will raise an `ArgumentError` if you attempt to write a property with the same name as an existing method.
374
+
375
+ #### Example:
376
+
377
+ ```ruby
378
+ class SafeMash < ::Hashie::Mash
379
+ include Hashie::Extensions::Mash::SafeAssignment
380
+ end
381
+
382
+ safe_mash = SafeMash.new
383
+ safe_mash.zip = 'Test' # => ArgumentError
384
+ ```
385
+
227
386
  ## Dash
228
387
 
229
388
  Dash is an extended Hash that has a discrete set of defined properties and only those properties may be set on the hash. Additionally, you can set defaults for each property. You can also flag a property as required. Required properties will raise an exception if unset.
data/RELEASING.md ADDED
@@ -0,0 +1,83 @@
1
+ # Releasing Hashie
2
+
3
+ There're no particular rules about when to release Hashie. Release bug fixes frequenty, features not so frequently and breaking API changes rarely.
4
+
5
+ ### Release
6
+
7
+ Run tests, check that all tests succeed locally.
8
+
9
+ ```sh
10
+ bundle install
11
+ bundle exec rake
12
+ ```
13
+
14
+ Check that the last build succeeded in [Travis CI](https://travis-ci.org/intridea/hashie) for all supported platforms.
15
+
16
+ Increment the version, modify [lib/hashie/version.rb](lib/hashie/version.rb).
17
+
18
+ * Increment the third number (minor version) if the release has bug fixes and/or very minor features, only (eg. change `0.5.1` to `0.5.2`).
19
+ * Increment the second number (patch version) if the release contains major features or breaking API changes (eg. change `0.5.1` to `0.6.0`).
20
+
21
+ Modify the "Stable Release" section in [README.md](README.md). Change the text to reflect that this is going to be the documentation for a stable release. Remove references to the previous release of Hashie. Keep the file open, you'll have to undo this change after the release.
22
+
23
+ ```markdown
24
+ ## Stable Release
25
+
26
+ You're reading the documentation for the stable release of Hashie, 3.3.0.
27
+ ```
28
+
29
+ Change "Next Release" in [CHANGELOG.md](CHANGELOG.md) to the new version.
30
+
31
+ ```markdown
32
+ 3.3.0 (8/25/2014)
33
+ =================
34
+ ```
35
+
36
+ Remove the line with "Your contribution here.", since there will be no more contributions to this release.
37
+
38
+ Commit your changes.
39
+
40
+ ```sh
41
+ git add README.md CHANGELOG.md lib/hashie/version.rb
42
+ git commit -m "Preparing for release, 3.3.0."
43
+ git push origin master
44
+ ```
45
+
46
+ Release.
47
+
48
+ ```sh
49
+ $ rake release
50
+
51
+ hashie 3.3.0 built to pkg/hashie-3.3.0.gem.
52
+ Tagged v3.3.0.
53
+ Pushed git commits and tags.
54
+ Pushed hashie 3.3.0 to rubygems.org.
55
+ ```
56
+
57
+ ### Prepare for the Next Version
58
+
59
+ Modify the "Stable Release" section in [README.md](README.md). Change the text to reflect that this is going to be the next release.
60
+
61
+ ```markdown
62
+ ## Stable Release
63
+
64
+ You're reading the documentation for the next release of Hashie, which should be 3.3.1.
65
+ The current stable release is [3.3.0](https://github.com/intridea/hashie/blob/v3.3.0/README.md).
66
+ ```
67
+
68
+ Add the next release to [CHANGELOG.md](CHANGELOG.md).
69
+
70
+ ```markdown
71
+ Next Release
72
+ ============
73
+
74
+ * Your contribution here.
75
+ ```
76
+
77
+ Commit your changes.
78
+
79
+ ```sh
80
+ git add CHANGELOG.md README.md
81
+ git commit -m "Preparing for next release."
82
+ git push origin master
83
+ ```
data/UPGRADING.md CHANGED
@@ -1,6 +1,22 @@
1
1
  Upgrading Hashie
2
2
  ================
3
3
 
4
+ ### Upgrading to 3.2.1
5
+
6
+ #### Possible coercion changes
7
+
8
+ The improvements made to coercions in version 3.2.1 [issue #200](https://github.com/intridea/hashie/pull/200) do not break the documented API, but are significant enough that changes may effect undocumented side-effects. Applications that depended on those side-effects will need to be updated.
9
+
10
+ **Change**: Type coercion no longer creates new objects if the input matches the target type. Previously coerced properties always resulted in the creation of a new object, even when it wasn't necessary. This had the effect of a `dup` or `clone` on coerced properties but not uncoerced ones.
11
+
12
+ If necessary, `dup` or `clone` your own objects. Do not assume Hashie will do it for you.
13
+
14
+ **Change**: Failed coercion attempts now raise Hashie::CoercionError.
15
+
16
+ Hashie now raises a Hashie::CoercionError that details on the property that could not be coerced, the source and target type of the coercion, and the internal error. Previously only the internal error was raised.
17
+
18
+ Applications that were attempting to rescuing the internal errors should be updated to rescue Hashie::CoercionError instead.
19
+
4
20
  ### Upgrading to 3.0
5
21
 
6
22
  #### Compatibility with Rails 4 Strong Parameters
data/lib/hashie.rb CHANGED
@@ -21,15 +21,20 @@ module Hashie
21
21
  autoload :StringifyKeys, 'hashie/extensions/stringify_keys'
22
22
  autoload :SymbolizeKeys, 'hashie/extensions/symbolize_keys'
23
23
  autoload :DeepFetch, 'hashie/extensions/deep_fetch'
24
+ autoload :DeepFind, 'hashie/extensions/deep_find'
24
25
  autoload :PrettyInspect, 'hashie/extensions/pretty_inspect'
25
26
  autoload :KeyConversion, 'hashie/extensions/key_conversion'
26
27
 
27
- module Mash
28
- autoload :ActiveModel, 'hashie/extensions/mash/active_model'
28
+ module Parsers
29
+ autoload :YamlErbParser, 'hashie/extensions/parsers/yaml_erb_parser'
29
30
  end
30
31
 
31
32
  module Dash
32
33
  autoload :IndifferentAccess, 'hashie/extensions/dash/indifferent_access'
33
34
  end
35
+
36
+ module Mash
37
+ autoload :SafeAssignment, 'hashie/extensions/mash/safe_assignment'
38
+ end
34
39
  end
35
40
  end