Skip to content

Instantly share code, notes, and snippets.

@TsubasaKawajiri
Last active February 14, 2023 13:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TsubasaKawajiri/e5f58bd1a587de26e748b869f42e1ce3 to your computer and use it in GitHub Desktop.
Save TsubasaKawajiri/e5f58bd1a587de26e748b869f42e1ce3 to your computer and use it in GitHub Desktop.
# ===== Usage =====
# def hoge
# "called"
# "hoge"
# end
#
# hash = Hash.new
# hash[:hoge] = hoge()
# called
# => "hoge"
# hash[:hoge]
# => "hoge"
#
# lazy_hash = LazyHash.new
# lazy_hash[:hoge] { hoge() }
# => #<Proc:0x00005628d3a582d0>
# lazy_hash[:hoge]
# called
# => "hoge"
#
# lazy_hash.promise
# => {:hoge=>#<Proc:0x00005628d3a582d0>}
#
# lazy_hash.thunk
# => {:hoge=>"hoge"}
class LazyHash < Hash
attr_reader :thunk, :promise
def initialize(ifnone = nil)
@thunk = Hash.new
@promise = Hash.new
super
end
def [](key, &block)
if block_given?
write(key, &block)
else
read(key)
end
end
def force!
keys.each do |key|
@thunk[key] = fetch(key).call
end
@thunk
end
def thunk_delete(key)
if key.nil?
thunk_delete_all
else
thunk_delete_with_key(key)
end
end
def delete(key, &block)
thunk_delete(key)
super(key, &block)
end
private
def write(key, &block)
proc = Proc.new(&block)
@promise[key] = proc
store(key, proc)
proc
end
def read(key)
return @thunk[key] if @thunk[key].present?
value = fetch(key)
@thunk[key] = value.is_a?(Proc) ? value.call : value
end
def thunk_delete_all
@thunk = Hash.new
end
def thunk_delete_with_key(key)
@thunk.delete(key)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment