Skip to content

Commit

Permalink
Add Hashie::Extensions::Mash::SafeAssignment
Browse files Browse the repository at this point in the history
This is part 3 of 3 of the to-do list determined in #198.
  • Loading branch information
michaelherold authored and dblock committed Aug 20, 2014
1 parent 1dce1d0 commit 6a2fac9
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions lib/hashie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,9 @@ module Parsers
module Dash
autoload :IndifferentAccess, 'hashie/extensions/dash/indifferent_access'
end

module Mash
autoload :SafeAssignment, 'hashie/extensions/mash/safe_assignment'
end
end
end
13 changes: 13 additions & 0 deletions lib/hashie/extensions/mash/safe_assignment.rb
Original file line number Diff line number Diff line change
@@ -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
7 changes: 6 additions & 1 deletion lib/hashie/mash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ def deep_update(other_hash, &blk)
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)
Expand Down Expand Up @@ -201,7 +206,7 @@ def method_missing(method_name, *args, &blk)
name, suffix = method_suffix(method_name)
case suffix
when '='
self[name] = args.first
assign_property(name, args.first)
when '?'
!!self[name]
when '!'
Expand Down
17 changes: 17 additions & 0 deletions spec/hashie/extensions/mash/safe_assignment_spec.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 6a2fac9

Please sign in to comment.