From 0af4c2f54f49d2bc294fab2215cf40121dc35da0 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sat, 25 Aug 2018 18:25:21 -0600 Subject: [PATCH] Add lazy class --- src/spectator/lazy.cr | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/spectator/lazy.cr diff --git a/src/spectator/lazy.cr b/src/spectator/lazy.cr new file mode 100644 index 0000000..f76d30e --- /dev/null +++ b/src/spectator/lazy.cr @@ -0,0 +1,34 @@ +module Spectator + # Lazy initialization of a value. + # Constructs a value only once by calling a `Proc`. + # The value is then stored and reused - the `Proc` is only called once. + struct Lazy(T) + @value_or_block : Proc(T) | T + + # Creates a lazy instance. + # The block provided to this method will be called + # when `#value` is invoked. + # The block will only be called once, + # and the result of the block will be cached. + def initialize(&block : -> T) + @value_or_block = block + end + + # Retrieves the lazy initialized value. + # The first call to this method will create the value. + # Subsequent calls will return the same value. + def value : T + if value = @value_or_block.as?(T) + return value + else + @value_or_block = construct + end + end + + # Calls the block used to construct the value. + # This method can only be called once per instance. + private def construct : T + @value_or_block.as(Proc(T)).call + end + end +end