Sha256: 1acee0b446e1b9aad2f79b1494f109f556d155c51bc585db9b5b19b0ccb7b389

Contents?: true

Size: 1.46 KB

Versions: 13

Compression:

Stored size: 1.46 KB

Contents

require 'hashie/mash'

module Interpol
  # Hashie::Mash is awesome: it gives us dot/method-call syntax for a hash.
  # This is perfect for dealing with structured JSON data.
  # The downside is that Hashie::Mash responds to anything--it simply
  # creates a new entry in the backing hash.
  #
  # DynamicStruct freezes a Hashie::Mash so that it no longer responds to
  # everything.  This is handy so that consumers of this gem can distinguish
  # between a fat-fingered field, and a field that is set to nil.
  module DynamicStruct
    SAFE_METHOD_MISSING = ::Hashie::Mash.superclass.instance_method(:method_missing)

    Mash = Class.new(::Hashie::Mash) do
      undef sort
    end

    def self.new(*args)
      Mash.new(*args).tap do |mash|
        mash.extend(self)
      end
    end

    def self.extended(mash)
      recursively_extend(mash)
    end

    def self.recursively_extend(object)
      case object
        when Array
          object.each { |v| recursively_extend(v) }
        when Mash
          object.extend(self) unless object.is_a?(self)
          object.each { |_, v| recursively_extend(v) }
      end
    end

    def method_missing(method_name, *args, &blk)
      if key = method_name.to_s[/\A([^?=]*)[?=]?\z/, 1]
        unless has_key?(key)
          return safe_method_missing(method_name, *args, &blk)
        end
      end

      super
    end

  private

    def safe_method_missing(*args)
      SAFE_METHOD_MISSING.bind(self).call(*args)
    end
  end
end

Version data entries

13 entries across 13 versions & 1 rubygems

Version Path
interpol-0.11.0 lib/interpol/dynamic_struct.rb
interpol-0.10.7 lib/interpol/dynamic_struct.rb
interpol-0.10.6 lib/interpol/dynamic_struct.rb
interpol-0.10.5 lib/interpol/dynamic_struct.rb
interpol-0.10.4 lib/interpol/dynamic_struct.rb
interpol-0.10.3 lib/interpol/dynamic_struct.rb
interpol-0.10.2 lib/interpol/dynamic_struct.rb
interpol-0.10.1 lib/interpol/dynamic_struct.rb
interpol-0.10.0 lib/interpol/dynamic_struct.rb
interpol-0.9.0 lib/interpol/dynamic_struct.rb
interpol-0.8.1 lib/interpol/dynamic_struct.rb
interpol-0.8.0 lib/interpol/dynamic_struct.rb
interpol-0.7.3 lib/interpol/dynamic_struct.rb