Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Do not redefined Hash#[]= method

Issue #112
Issue #98
  • Loading branch information...
commit 01922f8c07df1c707695a045f21a88c951f0b5e8 1 parent 68793d2
Sergey Potapov greyblake authored
33 lib/virtus/attribute/hash.rb
View
@@ -92,38 +92,13 @@ def initialize(*)
def coerce(value)
coerced = super
return coerced unless coerced.respond_to?(:each_with_object)
- coerced.each_with_object(new_hash) do |key_and_value, hash|
- hash[key_and_value[0]] = key_and_value[1]
+ coerced.each_with_object({}) do |key_and_value, hash|
+ key = @key_type_instance.coerce(key_and_value[0])
+ value = @value_type_instance.coerce(key_and_value[1])
+ hash[key] = value
end
end
- # Return an instance of the Hash with redefined []= method to coerce
- # keys and values on assigning.
- #
- # @return [Hash]
- #
- # @api private
- def new_hash
- hash = self.class.primitive.new
- return hash unless @key_type_instance && @value_type_instance
-
- key_coercion_method = @key_type_instance.coercion_method
- value_coercion_method = @value_type_instance.coercion_method
-
- # Redefine []= method to coerce key and value on assigning.
- # It requires inlining of Attribute#coerce method to coerce.
- # An alternative way would be using define_singleton_method or Sinatra's meta_def.
- hash.instance_eval(<<-eorb, __FILE__, __LINE__+1)
- def []=(key, value) # def []=(key, value)
- coerced_key = Virtus::Coercion[key.class].#{key_coercion_method}(key) # coerced_key = Virtus::Coercion[key.class].to_sym(key)
- coerced_value = Virtus::Coercion[value.class].#{value_coercion_method}(value) # coerced_value = Virtus::Coercion[value.class].to_f(value)
- super(coerced_key, coerced_value) # super(coerced_key, coerced_value)
- end # end
- eorb
-
- hash
- end
-
end # class Hash
end # class Attribute
end # module Virtus
14 spec/integration/hash_attributes_coercion_spec.rb
View
@@ -33,20 +33,6 @@ class Package
dimensions[:height].should be_eql(2.0)
dimensions[:length].should be_eql(4.5)
end
-
- context 'assign new value' do
- before do
- dimensions['width'] = 15
- end
-
- it 'should coerce key' do
- dimensions[:width].should == 15
- end
-
- it 'should not add new keys' do
- dimensions.keys.should =~ [:width, :height, :length]
- end
- end
end
describe '#meta_info' do
43 spec/unit/virtus/attribute/hash/new_hash_spec.rb
View
@@ -1,43 +0,0 @@
-require 'spec_helper'
-
-describe Virtus::Attribute::Hash, '#new_hash' do
- subject { object.new_hash }
-
- let(:options) { {} }
- let(:object) { Virtus::Attribute::Hash.new('stuff', options) }
-
- it { should be_instance_of(::Hash) }
-
-
- context '`:key_type` and `:value_type` options' do
- before do
- subject[:one] = 1
- subject[2] = '2.0'
- end
-
- context 'are undefined' do
- it 'should not coerce keys on assigning' do
- subject.keys.should =~ [:one, 2]
- end
-
- it 'should not coerce values on assigning' do
- subject.values.should =~ [1, '2.0']
- end
- end
-
- context 'are defined' do
- let(:options) {{
- :key_type => String,
- :value_type => Integer
- }}
-
- it 'should coerce keys on assigning' do
- subject.keys.should =~ ['one', '2']
- end
-
- it 'should coerce values on assigning' do
- subject.values.should =~ [1, 2]
- end
- end
- end
-end
Please sign in to comment.
Something went wrong with that request. Please try again.