Skip to content

Instantly share code, notes, and snippets.

@firedev
Created October 9, 2015 03:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save firedev/9de91e245f70c2e963e4 to your computer and use it in GitHub Desktop.
Save firedev/9de91e245f70c2e963e4 to your computer and use it in GitHub Desktop.
class BottomlessHash < Hash
def initialize
super &-> h, k { h[k] = self.class.new }
end
def self.from_hash(hash)
new.merge(hash)
end
end
class Hash
def bottomless
BottomlessHash.from_hash(self)
end
end
describe BottomlessHash do
subject { described_class.new }
it 'does not raise on missing key' do
expect do
subject[:missing][:key]
end.to_not raise_error
end
it 'returns an empty value on missing key' do
expect(subject[:missing][:key]).to be_empty
end
it 'stores and returns keys' do
subject[:existing][:key] = :value
expect(subject[:existing][:key]).to eq :value
end
describe '#from_hash' do
let (:hash) do
{ existing: { key: { value: :hello } } }
end
subject do
described_class.from_hash(hash)
end
it 'returns old hash values' do
expect(subject[:existing][:key][:value]).to eq :hello
end
it 'provides a bottomless version' do
expect(subject[:missing][:key]).to be_empty
end
it 'stores and returns new values' do
subject[:existing][:key] = :value
expect(subject[:existing][:key]).to eq :value
end
it 'converts nested hashes as well' do
expect do
subject[:existing][:key][:missing]
end.to_not raise_error
end
end
end
@rymai
Copy link

rymai commented Oct 9, 2015

Nice trick! 👍

@flyerhzm
Copy link

@firedev do you consider make it as a gem?

@firedev
Copy link
Author

firedev commented Oct 10, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment