Created
April 12, 2015 23:42
-
-
Save smedstadc/5daf8e8ad76036ce4f52 to your computer and use it in GitHub Desktop.
Read Only Ruby Hash Snippet
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
# By extending a regular ruby hash with this module the hash will behave as if | |
# it were an immutable object. The brackets and fetch methods will return copies | |
# of values and the assignment method will raise an exception. | |
# | |
# Other methods that should be redefined for a truly immutable hash object. | |
# :delete, :delete_if, :reject!, :select!, :keep_if, :merge!, :update | |
module ReadOnlyHash | |
def [](key) | |
value = super(key) | |
value ? value.dup : default | |
end | |
def []=(key, value) | |
raise StandardError, "assignment on a read only hash" | |
end | |
def fetch(key) | |
super(key).dup | |
end | |
def fetch(key, default) | |
value = super(key, default) | |
value ? value.dup : default | |
end | |
def fetch(key, &block) | |
if has_key?(key) | |
super(key).dup | |
else | |
yield | |
end | |
end | |
end | |
# Example: | |
# require_relative 'read_only_hash' | |
# Create a hash and set it up with any values it should contain. | |
hash = {foo: "bar", baz: "qux"} | |
hash[:zux] = "cav" | |
# Extend the hash with new read-only behavior | |
hash.extend(ReadOnlyHash) | |
hash[:baz] | |
# => "qux" | |
hash.fetch(:foo) | |
# => "bar" | |
x = hash[:zux] | |
x = "changed it" | |
hash[:zux] | |
# => "cav" | |
hash[:incorrect_key] | |
# => nil | |
hash.fetch(:incorrect_key) | |
# => KeyError: key not found: :incorrect_key | |
hash.fetch(:incorrect_key, "a default value") | |
# => "a default value" | |
hash.fetch(:incorrect_key) { puts "executing block because key was not found" } | |
# => "executing block because key was not found" | |
hash[:foo] = "new value" | |
# => StandardError: assignment on a read only hash |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment