Skip to content

Instantly share code, notes, and snippets.

@smedstadc
Created April 12, 2015 23:42
Show Gist options
  • Save smedstadc/5daf8e8ad76036ce4f52 to your computer and use it in GitHub Desktop.
Save smedstadc/5daf8e8ad76036ce4f52 to your computer and use it in GitHub Desktop.
Read Only Ruby Hash Snippet
# 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