Skip to content

Commit

Permalink
Merge branch 'master' into 331_new_feature
Browse files Browse the repository at this point in the history
* master:
  Fix support for Array#dig
  Preparing for the next development iteration, 3.4.5.
  Preparing for release, 3.4.4.
  Omit `return'
  Fix too fexible regex
  Refactor IgnoreUndeclared#initialize_attributes.
  Stringified translations wasn't working in IgnoreUndeclared.
  Convert Mash keys for #dig
  README: fix typo
  Update the change log format
  Fix `#merge` breaking indifferent access
  Fix build: ignore rbx-2 failures and add ruby 2.3.0.
  README: Clarified IndifferentAccess docs
  • Loading branch information
gipcompany committed Jul 14, 2016
2 parents 3d3282e + cfd6495 commit 6137e57
Show file tree
Hide file tree
Showing 20 changed files with 503 additions and 99 deletions.
14 changes: 7 additions & 7 deletions .rubocop_todo.yml
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2015-10-25 15:28:03 -0400 using RuboCop version 0.34.2.
# on 2016-06-01 14:51:33 -0700 using RuboCop version 0.34.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand All @@ -18,23 +18,23 @@ Metrics/AbcSize:
# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 171
Max: 179

# Offense count: 6
Metrics/CyclomaticComplexity:
Max: 11

# Offense count: 218
# Offense count: 231
# Configuration parameters: AllowURI, URISchemes.
Metrics/LineLength:
Max: 170

# Offense count: 17
# Offense count: 16
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 28

# Offense count: 6
# Offense count: 5
Metrics/PerceivedComplexity:
Max: 10

Expand All @@ -43,7 +43,7 @@ Style/CaseEquality:
Exclude:
- 'lib/hashie/hash.rb'

# Offense count: 27
# Offense count: 32
# Configuration parameters: Exclude.
Style/Documentation:
Enabled: false
Expand All @@ -57,7 +57,7 @@ Style/DoubleNegation:
- 'lib/hashie/mash.rb'
- 'spec/hashie/extensions/coercion_spec.rb'

# Offense count: 3
# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues.
Style/HashSyntax:
Expand Down
5 changes: 3 additions & 2 deletions .travis.yml
Expand Up @@ -3,12 +3,12 @@ sudo: false
cache: bundler

rvm:
- 2.3.0
- 2.2.3
- 2.1.7
- 2.0.0
- 1.9.3
- rbx-2.5.8
- rbx-2.2.10
- rbx-2
- jruby-19mode
- jruby-head
- ruby-head
Expand All @@ -17,3 +17,4 @@ matrix:
allow_failures:
- rvm: ruby-head
- rvm: jruby-head
- rvm: rbx-2
316 changes: 252 additions & 64 deletions CHANGELOG.md

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion CONTRIBUTING.md
Expand Up @@ -52,7 +52,17 @@ Document any external behavior in the [README](README.md).

#### Update Changelog

Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. Make it look like every other line, including your name and link to your Github account.
Add a line to [CHANGELOG](CHANGELOG.md) under *Unreleased*. Make it look like every other line, including your name and link to your Github account.

There are several categorizations of changes that you can choose from. Add your line to the appropriate section, following these conventions:

* **Added** - When you add a new behavior to any class or module (or add a new extension) that does not break backwards compatibility, you should mark it as "added". This is generally a fully new behavior that does not touch any pre-existing public API. Changes here require a MINOR version bump, following the Semantic Versioning specification.
* **Changed** - You should mark any change to the behavior of a public API on any class or module as "changed". Changes here require a MAJOR version bump, following the Semantic Versioning specification.
* **Deprecated** - Any time you deprecate part of the public API on any class or module you should mark the change as "deprecated". Deprecated behavior will be removed in the next MAJOR version bump, but should be left in until then. Changes here require a MINOR version bump, following the Semantic Versioning specification.
* **Removed** - You should mark any behavior that you removed from a public API on any class or module as "removed". Changes here require a MAJOR version bump, following the Semantic Versioning specification.
* **Fixed** - Any time you fix a bug you should mark as "fixed". Changes here require a PATCH version bump.
* **Security** - You should mark any security issue that you fix as "security". Changes here require a PATCH version bump.
* **Miscellaneous** - Mark any other changes you make (i.e. documentation updates, test harness changes, etc.) as "miscellaneous". Changes here require a PATCH version bump.

#### Commit Changes

Expand Down
35 changes: 28 additions & 7 deletions README.md
Expand Up @@ -20,11 +20,11 @@ $ gem install hashie

## Upgrading

You're reading the documentation for the next release of Hashie, which should be 3.4.4. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version. The current stable release is [3.4.3](https://github.com/intridea/hashie/blob/v3.4.3/README.md).
You're reading the documentation for the next release of Hashie, which should be 3.4.5. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version. The current stable release is [3.4.4](https://github.com/intridea/hashie/blob/v3.4.4/README.md).

## Hash Extensions

The library is broken up into a number of atomically includeable Hash extension modules as described below. This provides maximum flexibility for users to mix and match functionality while maintaining feature parity with earlier versions of Hashie.
The library is broken up into a number of atomically includable Hash extension modules as described below. This provides maximum flexibility for users to mix and match functionality while maintaining feature parity with earlier versions of Hashie.

Any of the extensions listed below can be mixed into a class by `include`-ing `Hashie::Extensions::ExtensionName`.

Expand Down Expand Up @@ -135,11 +135,11 @@ class Tweet < Hash
coerce_key :retweeted, ->(v) do
case v
when String
return !!(v =~ /^(true|t|yes|y|1)$/i)
!!(v =~ /\A(true|t|yes|y|1)\z/i)
when Numeric
return !v.to_i.zero?
!v.to_i.zero?
else
return v == true
v == true
end
end
end
Expand Down Expand Up @@ -237,9 +237,30 @@ overriding.__zip #=> [[['zip', 'a-dee-doo-dah']]]

### IndifferentAccess

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.
This extension can be mixed in to your Hash subclass to allow you to use Strings or Symbols interchangeably as keys; similar to the `params` hash in Rails.

A unique feature of Hashie's IndifferentAccess mixin is that it will inject itself recursively into subhashes *without* reinitializing the hash in question. This means you can safely merge together indifferent and non-indifferent hashes arbitrarily deeply without worrying about whether you'll be able to `hash[:other][:another]` properly.
In addition, IndifferentAccess will also inject itself into sub-hashes so they behave the same.

Example:

```ruby
class MyHash < Hash
include Hashie::Extensions::MergeInitializer
include Hashie::Extensions::IndifferentAccess
end

myhash = MyHash.new(:cat => 'meow', 'dog' => 'woof')
myhash['cat'] # => "meow"
myhash[:cat] # => "meow"
myhash[:dog] # => "woof"
myhash['dog'] # => "woof"

# Auto-Injecting into sub-hashes.
myhash['fishes'] = {}
myhash['fishes'].class # => Hash
myhash['fishes'][:food] = 'flakes'
myhash['fishes']['food'] # => "flakes"
```

### IgnoreUndeclared

Expand Down
71 changes: 57 additions & 14 deletions RELEASING.md
Expand Up @@ -2,7 +2,7 @@

There're no particular rules about when to release Hashie. Release bug fixes frequenty, features not so frequently and breaking API changes rarely.

### Release
## Release

Run tests, check that all tests succeed locally.

Expand All @@ -13,10 +13,15 @@ bundle exec rake

Check that the last build succeeded in [Travis CI](https://travis-ci.org/intridea/hashie) for all supported platforms.

Increment the version, modify [lib/hashie/version.rb](lib/hashie/version.rb).
### Check Next Version

* 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`).
* 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`).
Increment the version, modify [lib/hashie/version.rb](lib/hashie/version.rb). [Changelog](CHANGELOG.md) entries should be helpfully categorized to assist in picking the next version number.

* 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`). These should be in the "Fixed", "Security", or "Miscellaneous" categories in the change log.
* 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`). These should be in the "Added" or "Deprecated" categories in the change log.
* Increment the first number (major version) if the release has any changed or removed behavior on public APIs (eg. change `0.5.1` to `1.0.0`). These should be in the "Changed" or "Removed" categories in the change log.

### Modify the Readme

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.

Expand All @@ -26,14 +31,19 @@ Modify the "Stable Release" section in [README.md](README.md). Change the text t
You're reading the documentation for the stable release of Hashie, 3.3.0.
```

Change "Next Release" in [CHANGELOG.md](CHANGELOG.md) to the new version.
### Modify the Changelog

Change "Unreleased" in [CHANGELOG.md](CHANGELOG.md) to the new version.

```markdown
3.3.0 (8/25/2014)
=================
## [3.3.0] - 2014-08-25

[3.3.0]: https://github.com/intridea/hashie/compare/v<LAST_VERSION>..v<THIS_VERSION>
```

Remove the line with "Your contribution here.", since there will be no more contributions to this release.
Replace `<LAST_VERSION>` and `<THIS_VERSION>` with the last and new-to-be-released versions to set up the compare view on Github.

Remove any sections that only have "Nothing yet." underneath them.

Commit your changes.

Expand All @@ -43,6 +53,8 @@ git commit -m "Preparing for release, 3.3.0."
git push origin master
```

### Push to RubyGems.org

Release.

```sh
Expand All @@ -54,7 +66,7 @@ Pushed git commits and tags.
Pushed hashie 3.3.0 to rubygems.org.
```

### Prepare for the Next Version
## Prepare for the Next Version

Modify the "Stable Release" section in [README.md](README.md). Change the text to reflect that this is going to be the next release.

Expand All @@ -65,19 +77,50 @@ You're reading the documentation for the next release of Hashie, which should be
The current stable release is [3.3.0](https://github.com/intridea/hashie/blob/v3.3.0/README.md).
```

Add the next release to [CHANGELOG.md](CHANGELOG.md).
Add new "Unreleased" section to [CHANGELOG.md](CHANGELOG.md) using this template:

```markdown
Next Release
============
## [Unreleased][unreleased]

[unreleased]: https://github.com/intridea/hashie/compare/v<THIS_VERSION>...master

### Added

* Nothing yet.

### Changed

* Nothing yet.

* Your contribution here.
### Deprecated

* Nothing yet.

### Removed

* Nothing yet.

### Fixed

* Nothing yet.

### Security

* Nothing yet.

### Miscellanous

* Nothing yet.
```

Replace `<THIS_VERSION>` with the newly released versions to set up the compare view on Github.

Increment the minor version, modify [lib/hashie/version.rb](lib/hashie/version.rb).

Commit your changes.

```sh
git add CHANGELOG.md README.md
git commit -m "Preparing for next release."
git commit -m "Preparing for next development iteration, 3.3.1."
git push origin master
```
6 changes: 6 additions & 0 deletions lib/hashie.rb
Expand Up @@ -7,6 +7,7 @@ module Hashie
autoload :Mash, 'hashie/mash'
autoload :Trash, 'hashie/trash'
autoload :Rash, 'hashie/rash'
autoload :Array, 'hashie/array'

module Extensions
autoload :Coercion, 'hashie/extensions/coercion'
Expand All @@ -27,6 +28,7 @@ module Extensions
autoload :KeyConversion, 'hashie/extensions/key_conversion'
autoload :MethodAccessWithOverride, 'hashie/extensions/method_access'
autoload :StrictKeyAccess, 'hashie/extensions/strict_key_access'
autoload :RubyVersionCheck, 'hashie/extensions/ruby_version_check'

module Parsers
autoload :YamlErbParser, 'hashie/extensions/parsers/yaml_erb_parser'
Expand All @@ -41,6 +43,10 @@ module Dash
module Mash
autoload :SafeAssignment, 'hashie/extensions/mash/safe_assignment'
end

module Array
autoload :PrettyInspect, 'hashie/extensions/array/pretty_inspect'
end
end

class << self
Expand Down
11 changes: 11 additions & 0 deletions lib/hashie/array.rb
@@ -0,0 +1,11 @@
module Hashie
class Array < ::Array
include Hashie::Extensions::Array::PrettyInspect
include Hashie::Extensions::RubyVersionCheck
with_minimum_ruby('2.3.0') do
def dig(*indexes)
super(*indexes.map { |idx| Integer(idx) })
end
end
end
end
19 changes: 19 additions & 0 deletions lib/hashie/extensions/array/pretty_inspect.rb
@@ -0,0 +1,19 @@
module Hashie
module Extensions
module Array
module PrettyInspect
def self.included(base)
base.send :alias_method, :array_inspect, :inspect
base.send :alias_method, :inspect, :hashie_inspect
end

def hashie_inspect
ret = "#<#{self.class} ["
ret << to_a.map(&:inspect).join(', ')
ret << ']>'
ret
end
end
end
end
end
7 changes: 5 additions & 2 deletions lib/hashie/extensions/ignore_undeclared.rb
Expand Up @@ -30,10 +30,13 @@ module Extensions
# p.email # => NoMethodError
module IgnoreUndeclared
def initialize_attributes(attributes)
return unless attributes
klass = self.class
translations = klass.respond_to?(:translations) && klass.translations
attributes.each_pair do |att, value|
next unless self.class.property?(att) || (self.class.respond_to?(:translations) && self.class.translations.include?(att.to_sym))
next unless klass.property?(att) || (translations && translations.include?(att))
self[att] = value
end if attributes
end
end

def property_exists?(property)
Expand Down
8 changes: 8 additions & 0 deletions lib/hashie/extensions/indifferent_access.rb
Expand Up @@ -133,6 +133,14 @@ def indifferent_replace(other_hash)
self
end

def merge(*)
super.convert!
end

def merge!(*)
super.convert!
end

protected

def hash_lacking_indifference?(other)
Expand Down
15 changes: 15 additions & 0 deletions lib/hashie/extensions/ruby_version_check.rb
@@ -0,0 +1,15 @@
module Hashie
module Extensions
module RubyVersionCheck
def self.included(base)
base.extend ClassMethods
end

module ClassMethods
def with_minimum_ruby(version)
yield if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(version)
end
end
end
end
end

0 comments on commit 6137e57

Please sign in to comment.