interpol 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,37 +1,34 @@
1
- require 'interpol/define_singleton_method' unless Object.method_defined?(:define_singleton_method)
1
+ require 'hashie/mash'
2
2
 
3
3
  module Interpol
4
- # Transforms an arbitrarily deeply nested hash into a dot-syntax
5
- # object. Useful as an alternative to a hash since it is "strongly typed"
6
- # in the sense that fat-fingered property names result in a NoMethodError,
7
- # rather than getting a nil as you would with a hash.
8
- class DynamicStruct
9
- attr_reader :attribute_names, :to_hash
10
-
11
- def initialize(hash)
12
- @to_hash = hash
13
- @attribute_names = hash.keys.map(&:to_sym)
14
-
15
- hash.each do |key, value|
16
- value = method_value_for(value)
17
- define_singleton_method(key) { value }
18
- define_singleton_method("#{key}?") { !!value }
19
- end
4
+ # Hashie::Mash is awesome: it gives us dot/method-call syntax for a hash.
5
+ # This is perfect for dealing with structured JSON data.
6
+ # The downside is that Hashie::Mash responds to anything--it simply
7
+ # creates a new entry in the backing hash.
8
+ #
9
+ # DynamicStruct freezes a Hashie::Mash so that it no longer responds to
10
+ # everything. This is handy so that consumers of this gem can distinguish
11
+ # between a fat-fingered field, and a field that is set to nil.
12
+ module DynamicStruct
13
+ DEFAULT_PROC = lambda do |hash, key|
14
+ raise NoMethodError, "undefined method `#{key}' for #{hash.inspect}"
20
15
  end
21
16
 
22
- private
23
-
24
- def method_value_for(hash_value)
25
- return self.class.new(hash_value) if hash_value.is_a?(Hash)
17
+ def self.new(source)
18
+ hash = Hashie::Mash.new(source)
19
+ recursively_freeze(hash)
20
+ hash
21
+ end
26
22
 
27
- if hash_value.is_a?(Array) && hash_value.all? { |v| v.is_a?(Hash) }
28
- return hash_value.map { |v| self.class.new(v) }
23
+ def self.recursively_freeze(object)
24
+ case object
25
+ when Array
26
+ object.each { |obj| recursively_freeze(obj) }
27
+ when Hash
28
+ object.default_proc = DEFAULT_PROC
29
+ recursively_freeze(object.values)
29
30
  end
30
-
31
- hash_value
32
31
  end
33
-
34
- include DefineSingletonMethod unless method_defined?(:define_singleton_method)
35
32
  end
36
33
  end
37
34
 
@@ -1,3 +1,3 @@
1
1
  module Interpol
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interpol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -171,6 +171,22 @@ dependencies:
171
171
  - - '='
172
172
  - !ruby/object:Gem::Version
173
173
  version: 0.6.1
174
+ - !ruby/object:Gem::Dependency
175
+ name: hashie
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ~>
180
+ - !ruby/object:Gem::Version
181
+ version: '1.2'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ~>
188
+ - !ruby/object:Gem::Version
189
+ version: '1.2'
174
190
  description: Interpol is a toolkit for working with API endpoint definition files,
175
191
  giving you a stub app, a schema validation middleware, and browsable documentation.
176
192
  email: