Clash: multiple bang notation calls

Added inheritance

Added multiple bang notation merging

Minor performace improvements - ends_with? is faster than regexp
This commit is contained in:
Bartosz Kopiński 2014-11-27 05:13:26 +01:00 committed by Luis Lavena
parent b65b849aec
commit b2acb098aa
3 changed files with 37 additions and 13 deletions

View File

@ -2,6 +2,7 @@
* [#317](https://github.com/intridea/hashie/pull/317): Ensure `Hashie::Extensions::MethodQuery` methods return boolean values - [@michaelherold](https://github.com/michaelherold).
* [#319](https://github.com/intridea/hashie/pull/319): Fix a regression from 3.4.1 where `Hashie::Extensions::DeepFind` is no longer indifference-aware - [@michaelherold](https://github.com/michaelherold).
* [#240](https://github.com/intridea/hashie/pull/240): Fixed nesting twice with Clash keys - [@bartoszkopinski](https://github.com/bartoszkopinski).
* Your contribution here.
## 3.4.3 (10/25/2015)

View File

@ -54,7 +54,7 @@ module Hashie
case args.length
when 1
val = args.first
val = self[key].merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
val = self.class.new(self[key]).merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
else
val = args
end
@ -64,22 +64,23 @@ module Hashie
end
def method_missing(name, *args) #:nodoc:
name = name.to_s
if name.match(/!$/) && args.empty?
if args.empty? && name.to_s.end_with?('!')
key = name[0...-1].to_sym
if self[key].nil?
self[key] = Clash.new({}, self)
elsif self[key].is_a?(::Hash) && !self[key].is_a?(Clash)
self[key] = Clash.new(self[key], self)
case self[key]
when NilClass
self[key] = self.class.new({}, self)
when Clash
self[key]
when Hash
self[key] = self.class.new(self[key], self)
else
fail ChainError, 'Tried to chain into a non-hash key.'
end
self[key]
elsif args.any?
key = name.to_sym
merge_store(key, *args)
merge_store(name, *args)
else
super
end
end
end

View File

@ -1,8 +1,6 @@
require 'spec_helper'
describe Hashie::Clash do
subject { Hashie::Clash.new }
it 'is able to set an attribute via method_missing' do
subject.foo('bar')
expect(subject[:foo]).to eq 'bar'
@ -45,4 +43,28 @@ describe Hashie::Clash do
expect(subject[:foo]).to be_nil
expect(subject[:hello]).to be_nil
end
it 'merges multiple bang notation calls' do
subject.where!.foo(123)
subject.where!.bar(321)
expect(subject).to eq(where: { foo: 123, bar: 321 })
end
it 'raises an exception when method is missing' do
expect { subject.boo }.to raise_error(NoMethodError)
end
describe 'when inherited' do
subject { Class.new(described_class).new }
it 'bang nodes are instances of a subclass' do
subject.where!.foo(123)
expect(subject[:where]).to be_instance_of(subject.class)
end
it 'merged nodes are instances of a subclass' do
subject.where(abc: 'def').where(hgi: 123)
expect(subject[:where]).to be_instance_of(subject.class)
end
end
end