module Hash::Extensions # Author: Tilo Sloboda , 2012-09-24 # Gist: https://gist.github.com/3778285 # # Mix-In Module Hash::Extensions::IndifferentAccess # # Adds "Hash with Indifferent Access" behavior to an existing Hash # without creating a copy of that Hash. # # Limitation: does not work for embedded hashes. # # Purpose: # When passing a parameter hash to Resque/Redis, the hash keys # get persisted as Strings, not Symbols. including this mix-in # into the param hash, allows to access the very same hash with symbols. # # e.g.: # def perform(params_hash) # class << params_hash # include Hash::Extensions::IndifferentAccess # add behavior without creating duplicate # end # params.create_symbols_only(true) # if new keys should be created as symbols # # # ... Rescue Worker Code # # end module IndifferentAccess def self.included(base) base.class_eval do alias_method :regular_write, :[]= %w(default update fetch delete key? values_at).each do |m| alias_method "regular_#{m}", m end # forces new hash keys to always be symbols; default: false def create_symbols_only( boolean=true ) @__CREATE_SYMBOLS_ONLY = boolean end def [](key) if self.include?(key) self.regular_fetch(key) # regular reader else if key.class == Symbol && self.include?(key.to_s) return self.regular_fetch( key.to_s ) elsif key.class == String && self.include?(key.to_sym) return self.regular_fetch( key.to_sym ) else return nil # the key wasn't defined end end end def []=(key,value) if self.include?(key) self.regular_write(key , value) else if key.class == Symbol && self.include?(key.to_s) self.regular_write(key.to_s , value) elsif key.class == String && self.include?(key.to_sym) self.regular_write(key.to_sym , value) else # new parameter which was not there before if @__CREATE_SYMBOLS_ONLY self.regular_write(key.to_sym, value) else self.regular_write(key, value) # whatever was handed in end end end end end # end of class eval end # end of included() end end