summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/hashie/extensions/coercion.rb32
-rw-r--r--lib/hashie/extensions/dash/indifferent_access.rb21
-rw-r--r--lib/hashie/extensions/dash/property_translation.rb4
-rw-r--r--lib/hashie/extensions/deep_locate.rb8
-rw-r--r--lib/hashie/extensions/indifferent_access.rb4
-rw-r--r--lib/hashie/extensions/mash/safe_assignment.rb4
-rw-r--r--lib/hashie/extensions/strict_key_access.rb9
-rw-r--r--lib/hashie/hash.rb25
-rw-r--r--lib/hashie/mash.rb13
9 files changed, 84 insertions, 36 deletions
diff --git a/lib/hashie/extensions/coercion.rb b/lib/hashie/extensions/coercion.rb
index e3f5011..88be97a 100644
--- a/lib/hashie/extensions/coercion.rb
+++ b/lib/hashie/extensions/coercion.rb
@@ -1,5 +1,9 @@
module Hashie
- class CoercionError < StandardError; end
+ class CoercionError < StandardError
+ def initialize(key, value, into, message)
+ super("Cannot coerce property #{key.inspect} from #{value.class} to #{into}: #{message}")
+ end
+ end
module Extensions
module Coercion
@@ -12,20 +16,22 @@ module Hashie
Symbol => :to_sym
}.freeze
- ABSTRACT_CORE_TYPES = if RubyVersion.new(RUBY_VERSION) >= RubyVersion.new('2.4.0')
- { Numeric => [Integer, Float, Complex, Rational] }
- else
- {
- Integer => [Fixnum, Bignum], # rubocop:disable Lint/UnifiedInteger
- Numeric => [Fixnum, Bignum, Float, Complex, Rational] # rubocop:disable Lint/UnifiedInteger
- }
- end
+ ABSTRACT_CORE_TYPES =
+ if RubyVersion.new(RUBY_VERSION) >= RubyVersion.new('2.4.0')
+ { Numeric => [Integer, Float, Complex, Rational] }
+ else
+ {
+ Integer => [Fixnum, Bignum], # rubocop:disable Lint/UnifiedInteger
+ Numeric => [Fixnum, Bignum, Float, Complex, Rational] # rubocop:disable Lint/UnifiedInteger
+ }
+ end
def self.included(base)
base.send :include, InstanceMethods
- base.extend ClassMethods # NOTE: we wanna make sure we first define set_value_with_coercion before extending
-
- base.send :alias_method, :set_value_without_coercion, :[]= unless base.method_defined?(:set_value_without_coercion)
+ base.extend ClassMethods
+ unless base.method_defined?(:set_value_without_coercion)
+ base.send :alias_method, :set_value_without_coercion, :[]=
+ end
base.send :alias_method, :[]=, :set_value_with_coercion
end
@@ -37,7 +43,7 @@ module Hashie
begin
value = self.class.fetch_coercion(into).call(value)
rescue NoMethodError, TypeError => e
- raise CoercionError, "Cannot coerce property #{key.inspect} from #{value.class} to #{into}: #{e.message}"
+ raise CoercionError.new(key, value, into, e.message)
end
end
diff --git a/lib/hashie/extensions/dash/indifferent_access.rb b/lib/hashie/extensions/dash/indifferent_access.rb
index 9d1b87b..204cae6 100644
--- a/lib/hashie/extensions/dash/indifferent_access.rb
+++ b/lib/hashie/extensions/dash/indifferent_access.rb
@@ -7,11 +7,23 @@ module Hashie
base.send :include, Hashie::Extensions::IndifferentAccess
end
+ def self.maybe_extend(base)
+ return unless requires_class_methods?(base)
+
+ base.extend(ClassMethods)
+ end
+
+ def self.requires_class_methods?(klass)
+ klass <= Hashie::Dash &&
+ !klass.singleton_class.included_modules.include?(ClassMethods)
+ end
+ private_class_method :requires_class_methods?
+
module ClassMethods
# Check to see if the specified property has already been
# defined.
def property?(name)
- name = translations[name.to_sym] if included_modules.include?(Hashie::Extensions::Dash::PropertyTranslation) && translation_exists?(name)
+ name = translations[name.to_sym] if translation_for?(name)
name = name.to_s
!!properties.find { |property| property.to_s == name }
end
@@ -30,6 +42,13 @@ module Hashie
name = name.to_s
!!transforms.keys.find { |key| key.to_s == name }
end
+
+ private
+
+ def translation_for?(name)
+ included_modules.include?(Hashie::Extensions::Dash::PropertyTranslation) &&
+ translation_exists?(name)
+ end
end
end
end
diff --git a/lib/hashie/extensions/dash/property_translation.rb b/lib/hashie/extensions/dash/property_translation.rb
index 85bfb89..f5bf081 100644
--- a/lib/hashie/extensions/dash/property_translation.rb
+++ b/lib/hashie/extensions/dash/property_translation.rb
@@ -58,7 +58,9 @@ module Hashie
end
def permitted_input_keys
- @permitted_input_keys ||= properties.map { |property| inverse_translations.fetch property, property }
+ @permitted_input_keys ||=
+ properties
+ .map { |property| inverse_translations.fetch property, property }
end
# Defines a property on the Trash. Options are as follows:
diff --git a/lib/hashie/extensions/deep_locate.rb b/lib/hashie/extensions/deep_locate.rb
index 3577e93..62e1be2 100644
--- a/lib/hashie/extensions/deep_locate.rb
+++ b/lib/hashie/extensions/deep_locate.rb
@@ -62,7 +62,7 @@ module Hashie
end
def self._construct_key_comparator(search_key, object)
- search_key = search_key.to_s if defined?(::ActiveSupport::HashWithIndifferentAccess) && object.is_a?(::ActiveSupport::HashWithIndifferentAccess)
+ search_key = search_key.to_s if activesupport_indifferent?(object)
search_key = search_key.to_s if object.respond_to?(:indifferent_access?) && object.indifferent_access?
lambda do |non_callable_object|
@@ -93,6 +93,12 @@ module Hashie
comparator.call(key, value, object)
end
private_class_method :_match_comparator?
+
+ def self.activesupport_indifferent?(object)
+ defined?(::ActiveSupport::HashWithIndifferentAccess) &&
+ object.is_a?(::ActiveSupport::HashWithIndifferentAccess)
+ end
+ private_class_method :activesupport_indifferent?
end
end
end
diff --git a/lib/hashie/extensions/indifferent_access.rb b/lib/hashie/extensions/indifferent_access.rb
index 4f5bd2c..e3d2d63 100644
--- a/lib/hashie/extensions/indifferent_access.rb
+++ b/lib/hashie/extensions/indifferent_access.rb
@@ -24,9 +24,7 @@ module Hashie
#
module IndifferentAccess
def self.included(base)
- Hashie::Extensions::Dash::IndifferentAccess::ClassMethods.tap do |extension|
- base.extend(extension) if base <= Hashie::Dash && !base.singleton_class.included_modules.include?(extension)
- end
+ Hashie::Extensions::Dash::IndifferentAccess.maybe_extend(base)
base.class_eval do
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
diff --git a/lib/hashie/extensions/mash/safe_assignment.rb b/lib/hashie/extensions/mash/safe_assignment.rb
index b1b2046..dcf7488 100644
--- a/lib/hashie/extensions/mash/safe_assignment.rb
+++ b/lib/hashie/extensions/mash/safe_assignment.rb
@@ -3,7 +3,9 @@ module Hashie
module Mash
module SafeAssignment
def custom_writer(key, *args) #:nodoc:
- raise ArgumentError, "The property #{key} clashes with an existing method." if !key?(key) && respond_to?(key, true)
+ if !key?(key) && respond_to?(key, true)
+ raise ArgumentError, "The property #{key} clashes with an existing method."
+ end
super
end
diff --git a/lib/hashie/extensions/strict_key_access.rb b/lib/hashie/extensions/strict_key_access.rb
index 0822c53..0edd698 100644
--- a/lib/hashie/extensions/strict_key_access.rb
+++ b/lib/hashie/extensions/strict_key_access.rb
@@ -15,12 +15,15 @@ module Hashie
# >> hash[:cow]
# KeyError: key not found: :cow
#
- # NOTE: For googlers coming from Python to Ruby, this extension makes a Hash behave more like a "Dictionary".
+ # NOTE: For googlers coming from Python to Ruby, this extension makes a Hash
+ # behave more like a "Dictionary".
#
module StrictKeyAccess
class DefaultError < StandardError
- def initialize(msg = 'Setting or using a default with Hashie::Extensions::StrictKeyAccess does not make sense', *args)
- super
+ def initialize
+ super(
+ 'Setting or using a default with Hashie::Extensions::StrictKeyAccess does not make sense'
+ )
end
end
diff --git a/lib/hashie/hash.rb b/lib/hashie/hash.rb
index 0eade03..7a97ef6 100644
--- a/lib/hashie/hash.rb
+++ b/lib/hashie/hash.rb
@@ -18,20 +18,21 @@ module Hashie
def to_hash(options = {})
out = {}
each_key do |k|
- assignment_key = if options[:stringify_keys]
- k.to_s
- elsif options[:symbolize_keys]
- k.to_s.to_sym
- else
- k
- end
+ assignment_key =
+ if options[:stringify_keys]
+ k.to_s
+ elsif options[:symbolize_keys]
+ k.to_s.to_sym
+ else
+ k
+ end
if self[k].is_a?(Array)
out[assignment_key] ||= []
self[k].each do |array_object|
- out[assignment_key] << (array_object.is_a?(Hash) ? flexibly_convert_to_hash(array_object, options) : array_object)
+ out[assignment_key] << maybe_convert_to_hash(array_object, options)
end
else
- out[assignment_key] = self[k].is_a?(Hash) || self[k].respond_to?(:to_hash) ? flexibly_convert_to_hash(self[k], options) : self[k]
+ out[assignment_key] = maybe_convert_to_hash(self[k], options)
end
end
out
@@ -44,6 +45,12 @@ module Hashie
private
+ def maybe_convert_to_hash(object, options)
+ return object unless object.is_a?(Hash) || object.respond_to?(:to_hash)
+
+ flexibly_convert_to_hash(object, options)
+ end
+
def flexibly_convert_to_hash(object, options = {})
if object.method(:to_hash).arity.zero?
object.to_hash
diff --git a/lib/hashie/mash.rb b/lib/hashie/mash.rb
index bc5873c..02ccc3f 100644
--- a/lib/hashie/mash.rb
+++ b/lib/hashie/mash.rb
@@ -16,8 +16,10 @@ module Hashie
# * No punctuation: Returns the value of the hash for that key, or nil if none exists.
# * Assignment (<tt>=</tt>): Sets the attribute of the given method name.
# * Existence (<tt>?</tt>): Returns true or false depending on whether that key has been set.
- # * Bang (<tt>!</tt>): Forces the existence of this key, used for deep Mashes. Think of it as "touch" for mashes.
- # * Under Bang (<tt>_</tt>): Like Bang, but returns a new Mash rather than creating a key. Used to test existance in deep Mashes.
+ # * Bang (<tt>!</tt>): Forces the existence of this key, used for deep Mashes. Think of it
+ # as "touch" for mashes.
+ # * Under Bang (<tt>_</tt>): Like Bang, but returns a new Mash rather than creating a key.
+ # Used to test existance in deep Mashes.
#
# == Basic Example
#
@@ -64,8 +66,11 @@ module Hashie
ALLOWED_SUFFIXES = %w[? ! = _].freeze
class CannotDisableMashWarnings < StandardError
- def initialize(message = 'You cannot disable warnings on the base Mash class. Please subclass the Mash and disable it in the subclass.')
- super(message)
+ def initialize
+ super(
+ 'You cannot disable warnings on the base Mash class. ' \
+ 'Please subclass the Mash and disable it in the subclass.'
+ )
end
end