Created
September 24, 2012 20:48
-
-
Save tilo/3778285 to your computer and use it in GitHub Desktop.
Hash mix-in to add IndifferentAccess behavior without duplicating a given hash instance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment