Class: APISmith::Smash
- Inherits:
-
Hashie::Dash
- Object
- Hashie::Dash
- APISmith::Smash
- Defined in:
- lib/api_smith/smash.rb
Overview
Extends Hashie::Dash to suppress unknown keys when passing data, but is configurable to raises an UnknownKey exception when accessing keys in the Smash.
APISmith::Smash is a subclass of Hashie::Dash that adds several features making it suitable for use in writing api clients. Namely,
-
The ability to silence exceptions on unknown keys (vs. Raising NoMethodError)
-
The ability to define conversion of incoming data via transformers
-
The ability to define aliases for keys via the from parameter.
Defined Under Namespace
Classes: UnknownKey
Class Method Summary collapse
-
.call(value) ⇒ Array<Smash>, Smash
Automates type conversion (including on Array and Hashes) to this type.
-
.exception_on_unknown_key=(value) ⇒ Object
Sets whether or not Smash should raise NoMethodError on an unknown key.
-
.exception_on_unknown_key? ⇒ Boolean
Test if the object should raise a NoMethodError exception on unknown property accessors or whether it should be silenced.
-
.inherited(klass) ⇒ Object
Hook to make it inherit instance variables correctly.
-
.key_mapping ⇒ Object
Returns a class-specific hash of incoming keys and their resultant property name, useful for mapping non-standard names (e.g. displayName) to their more ruby-like equivelant (e.g. display_name).
-
.property(property_name, options = {}) ⇒ Object
Create a new property (i.e., hash key) for this Object type.
-
.property?(key) ⇒ Boolean
Does this Smash class contain a specific property (key), or does it have a key mapping (via :from).
-
.transformer_for(key, value = nil, &blk) ⇒ Object
Sets the transformer that is invoked when the given key is set.
-
.transformers ⇒ Object
Returns a class-specific hash of transformers, containing the attribute name mapped to the transformer that responds to call.
Instance Method Summary collapse
-
#[](property) ⇒ Object
Access the value responding to a key, normalising the key into a form we know (e.g. processing the from value to convert it to the actual property name).
-
#[]=(property, value) ⇒ Object
Sets the value for a given key.
Class Method Details
.call(value) ⇒ Array<Smash>, Smash
Automates type conversion (including on Array and Hashes) to this type. Used so we can pass this class similarily to how we pass lambdas as an object, primarily for use as transformers.
138 139 140 141 142 143 144 145 146 |
# File 'lib/api_smith/smash.rb', line 138 def self.call(value) if value.is_a?(Array) value.map { |v| call v }.compact elsif value.is_a?(Hash) new value else nil end end |
.exception_on_unknown_key=(value) ⇒ Object
Sets whether or not Smash should raise NoMethodError on an unknown key. Sets it for the current class.
71 72 73 |
# File 'lib/api_smith/smash.rb', line 71 def self.exception_on_unknown_key=(value) @exception_on_unknown_key = value end |
.exception_on_unknown_key? ⇒ Boolean
Test if the object should raise a NoMethodError exception on unknown property accessors or whether it should be silenced.
63 64 65 |
# File 'lib/api_smith/smash.rb', line 63 def self.exception_on_unknown_key? defined?(@exception_on_unknown_key) && @exception_on_unknown_key end |
.inherited(klass) ⇒ Object
Hook to make it inherit instance variables correctly. Called once the Smash is inherited from in another object to maintain state.
93 94 95 96 97 98 |
# File 'lib/api_smith/smash.rb', line 93 def self.inherited(klass) super klass.instance_variable_set '@transformers', transformers.dup klass.instance_variable_set '@key_mapping', key_mapping.dup klass.instance_variable_set '@exception_on_unknown_key', exception_on_unknown_key? end |
.key_mapping ⇒ Object
Returns a class-specific hash of incoming keys and their resultant property name, useful for mapping non-standard names (e.g. displayName) to their more ruby-like equivelant (e.g. display_name).
54 55 56 |
# File 'lib/api_smith/smash.rb', line 54 def self.key_mapping (@key_mapping ||= {}) end |
.property(property_name, options = {}) ⇒ Object
Create a new property (i.e., hash key) for this Object type. This method allows for converting property names and defining custom transformers for more complex types.
109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/api_smith/smash.rb', line 109 def self.property(property_name, = {}) super if [:from] property_name = property_name.to_s Array([:from]).each do |k| key_mapping[k.to_s] = property_name end end if [:transformer] transformer_for property_name, [:transformer] end end |
.property?(key) ⇒ Boolean
Does this Smash class contain a specific property (key), or does it have a key mapping (via :from)
127 128 129 |
# File 'lib/api_smith/smash.rb', line 127 def self.property?(key) super || key_mapping.has_key?(key.to_s) end |
.transformer_for(key, value = nil, &blk) ⇒ Object
Sets the transformer that is invoked when the given key is set.
81 82 83 84 85 86 87 88 89 |
# File 'lib/api_smith/smash.rb', line 81 def self.transformer_for(key, value = nil, &blk) if blk.nil? && value blk = value.respond_to?(:call) ? value : value.to_sym.to_proc end raise ArgumentError, 'must provide a transformation' if blk.nil? transformers[key.to_s] = blk # For each subclass, set the transformer. Array(@subclasses).each { |klass| klass.transformer_for(key, value) } end |
.transformers ⇒ Object
Returns a class-specific hash of transformers, containing the attribute name mapped to the transformer that responds to call.
46 47 48 |
# File 'lib/api_smith/smash.rb', line 46 def self.transformers (@transformers ||= {}) end |
Instance Method Details
#[](property) ⇒ Object
Access the value responding to a key, normalising the key into a form we know (e.g. processing the from value to convert it to the actual property name).
154 155 156 157 158 |
# File 'lib/api_smith/smash.rb', line 154 def [](property) super transform_key(property) rescue UnknownKey nil end |
#[]=(property, value) ⇒ Object
Sets the value for a given key. Transforms the key first (e.g. taking into account from values) and transforms the property using any transformers.
166 167 168 169 170 171 |
# File 'lib/api_smith/smash.rb', line 166 def []=(property, value) key = transform_key(property) super key, transform_property(key, value) rescue UnknownKey nil end |