Add Hashie::Extensions::Mash::SafeAssignment

This is part 3 of 3 of the to-do list determined in #198.
This commit is contained in:
Michael Herold 2014-08-18 13:00:05 -05:00 committed by dblock
parent 1dce1d08b3
commit 6a2fac91e9
6 changed files with 57 additions and 2 deletions

View File

@ -5,8 +5,9 @@
* [#197](https://github.com/intridea/hashie/pull/197): Dont convert keys to string on initalization of mash - [@gregory](https://github.com/gregory).
* [#201](https://github.com/intridea/hashie/pull/201): Hashie::Trash transforms can be inherited - [@fobocaster](https://github.com/fobocaster).
* [#189](https://github.com/intridea/hashie/pull/189): Added Rash#fetch - [@medcat](https://github.com/medcat).
* [#204](https://github.com/intridea/hashie/pull/204): Added Hashie::Extensions::MethodOverridingWriter and Hashie::Extensions::MethodAccessWithOverride - [@michaelherold](https://github.com/michaelherold).
* [#200](https://github.com/intridea/hashie/pull/200): Improved coercion: primitives and error handling - [@maxlinc](https://github.com/maxlinc).
* [#204](https://github.com/intridea/hashie/pull/204): Added Hashie::Extensions::MethodOverridingWriter and Hashie::Extensions::MethodAccessWithOverride - [@michaelherold](https://github.com/michaelherold).
* [#205](http://github.com/intridea/hashie/pull/205): Added Hashie::Extensions::Mash::SafeAssignment - [@michaelherold](https://github.com/michaelherold).
* Your contribution here.
## 3.2.0 (7/10/2014)

View File

@ -342,6 +342,21 @@ mash = Mash.load('data/user.csv', parser: MyCustomCsvParser)
mash[1] #=> { name: 'John', lastname: 'Doe' }
```
### Mash Extension: SafeAssignment
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.
#### Example:
```ruby
class SafeMash < ::Hashie::Mash
include Hashie::Extensions::Mash::SafeAssignment
end
safe_mash = SafeMash.new
safe_mash.zip = 'Test' # => ArgumentError
```
## Dash
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.

View File

@ -31,5 +31,9 @@ module Hashie
module Dash
autoload :IndifferentAccess, 'hashie/extensions/dash/indifferent_access'
end
module Mash
autoload :SafeAssignment, 'hashie/extensions/mash/safe_assignment'
end
end
end

View File

@ -0,0 +1,13 @@
module Hashie
module Extensions
module Mash
module SafeAssignment
def assign_property(name, value)
fail ArgumentError, "The property #{name} clashes with an existing method." if methods.include?(name)
self[name] = value
end
end
end
end
end

View File

@ -160,6 +160,11 @@ module Hashie
alias_method :update, :deep_update
alias_method :merge!, :update
# Assigns a value to a key
def assign_property(name, value)
self[name] = value
end
# Performs a shallow_update on a duplicate of the current mash
def shallow_merge(other_hash)
dup.shallow_update(other_hash)
@ -201,7 +206,7 @@ module Hashie
name, suffix = method_suffix(method_name)
case suffix
when '='
self[name] = args.first
assign_property(name, args.first)
when '?'
!!self[name]
when '!'

View File

@ -0,0 +1,17 @@
require 'spec_helper'
describe Hashie::Extensions::Mash::SafeAssignment do
class MashWithSafeAssignment < Hashie::Mash
include Hashie::Extensions::Mash::SafeAssignment
end
context 'when included in Mash' do
subject { MashWithSafeAssignment.new }
context 'when attempting to override a method' do
it 'raises an error' do
expect { subject.zip = 'Test' }.to raise_error(ArgumentError)
end
end
end
end