Skip to content

Instantly share code, notes, and snippets.

@remcopeereboom
Created December 6, 2016 23:09
Show Gist options
  • Save remcopeereboom/c1711d42f8678872fac5343819bf4648 to your computer and use it in GitHub Desktop.
Save remcopeereboom/c1711d42f8678872fac5343819bf4648 to your computer and use it in GitHub Desktop.
Roundabout way of implementing promises in ruby.
class Promise < BasicObject
def initialize(&computation)
@computation = computation
end
def __result__
if @computation
@result = @computation.call
@computation = nil # So we don't redo the calculation next time.
end
@result
end
def inspect
if @computation
"#<Promise computation=#{@computation.inspect}>"
else
@result.inspect
end
end
# Calling this on anything other than the methods in the array below will
# force a computation!
def respond_to?(msg)
msg = msg.to_sym
Promise.instance_methods.include?(msg) || __result__.respond_to?(msg)
end
# Handle essentially all messages by delegating them to the result of
# Promise#__result__.
def method_missing(*a, &b)
__result__.__send__(*a, &b)
end
end
class Computation
attr_reader :expensive_to_calculate
def initialize
@expensive_to_calculate = promise { expensive_calculation }
end
private
def expensive_calculation
# ...
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment