module LazyStruct::Mixin

For mixing into an existing OpenStruct instance singleton class.

Public Instance Methods

attribute(reader, &block) click to toggle source

&block is evaluated when this attribute is requested. The same result is returned for subsquent calls, until the field is assigned a different value.

# File install.rb, line 462
def attribute(reader, &block)
  singleton = (class << self ; self ; end)
  singleton.instance_eval {
    #
    # Define a special reader method in the singleton class.
    #
    define_method(reader) {
      block.call.tap { |value|
        #
        # The value has been computed.  Replace this method with a
        # one-liner giving the value.
        #
        singleton.instance_eval {
          remove_method(reader)
          define_method(reader) { value }
        }
      }
    }
    
    #
    # Revert to the old OpenStruct behavior when the writer is called.
    #
    writer = "#{reader}=".to_sym
    define_method(writer) { |value|
      singleton.instance_eval {
        remove_method(reader)
        remove_method(writer)
      }
      method_missing(writer, value)
    }
  }
end