Fun with callcc
Fun code snippet
In Ruby, foo["bar"]["baz"]["foo"] = 1 on an empty hash blows up on nil. Here I patch Hash#[], nil.[] and nil.[]= with callcc so that the final assignment builds the missing hashes after the fact.
require "continuation"
class Hash
alias_method :_original_lookup, :[]
def [](key)
_original_lookup(key).tap do
callcc { |cc| $hash_cc = [cc]; nil }&.tap do |value_from_future|
self[key] = value_from_future
$hash_cc.pop.call(self)
end
end
end
end
def nil.[](key)
callcc { |cc| $hash_cc << cc; nil }&.tap do |value|
$hash_cc.pop.call(key => value)
end
end
def nil.[]=(key, value)
callcc { |cc|
$hash_cc.unshift(cc)
$hash_cc.pop.call(key => value)
}
end
foo = {}
foo["bar"]["baz"]["foo"] = 1
puts foo
Each lookup that comes up empty saves a continuation and returns nil. When nil.[]= finally runs, it jumps back into those saved lookups one by one, handing each a freshly built hash, until the original Hash#[] stores the result and resumes after the assignment. It prints {"bar"=>{"baz"=>{"foo"=>1}}}.
Gist: timetravel.rb