diff --git a/src/spectator/lazy_wrapper.cr b/src/spectator/lazy_wrapper.cr index 3939c95..9bc7125 100644 --- a/src/spectator/lazy_wrapper.cr +++ b/src/spectator/lazy_wrapper.cr @@ -4,6 +4,23 @@ require "./wrapper" module Spectator # Lazily stores a value of any type. # Combines `Lazy` and `Wrapper`. + # + # Contains no value until the first call to `#get` is made. + # Any type can be stored in this wrapper. + # However, the type must always be known when retrieving it via `#get`. + # The type is inferred from the block, and all blocks must return the same type. + # Because of this, it is recommended to only have `#get` called in one location. + # + # This type is expected to be used like so: + # ``` + # @wrapper : LazyWrapper + # + # # ... + # + # def lazy_load + # @wrapper.get { some_expensive_operation } + # end + # ``` struct LazyWrapper @lazy = Lazy(Wrapper).new @@ -11,7 +28,7 @@ module Spectator # On the first invocation of this method, it will yield. # The block should return the value to store. # Subsequent calls will return the same value and not yield. - def get(&block : -> T) : T forall T + def get(& : -> T) : T forall T wrapper = @lazy.get { Wrapper.new(yield) } wrapper.get { yield } end diff --git a/src/spectator/wrapper.cr b/src/spectator/wrapper.cr index b5edeb3..21bd0ec 100644 --- a/src/spectator/wrapper.cr +++ b/src/spectator/wrapper.cr @@ -2,6 +2,12 @@ module Spectator # Typeless wrapper for a value. # Stores any value or reference type. # However, the type must be known when retrieving the value. + # + # This type is expected to be used like so: + # ``` + # wrapper = Wrapper.new("wrapped") + # value = wrapper.get(String) + # ``` struct Wrapper @value : TypelessValue @@ -22,6 +28,12 @@ module Spectator # The block must return the same type as the wrapped value, otherwise an error will be raised. # This method gets around the issue where the value might be a type (i.e. `Int32.class`). # The block will never be executed, it is only used for type information. + # + # ``` + # wrapper = Wrapper.new(Int32) + # # type = wrapper.get(Int32.class) # Does not work! + # type = wrapper.get { Int32 } # Returns Int32 + # ``` def get(& : -> T) : T forall T value = @value.as(Value(T)) value.get