NAME

    Object::Pad::SlotAttr::LazyInit - lazily initialise Object::Pad slots
    at first read

SYNOPSIS

       use Object::Pad;
       use Object::Pad::SlotAttr::LazyInit;
    
       class Item {
          has $uuid :reader :param :LazyInit(_make_uuid);
    
          method _make_uuid {
             require Data::GUID;
             return Data::GUID->new->as_string;
          }
       }

DESCRIPTION

    This module provides a third-party slot attribute for Object::Pad-based
    classes, which declares that the slot it is attached to has a lazy
    initialisation method, which will be called the first time the slot's
    value is read from.

    WARNING The ability for Object::Pad to take third-party slot attributes
    is still new and highly experimental, and subject to much API change in
    future. As a result, this module should be considered equally
    experimental. As a further point, it is currently pinned to requiring
    an exact $Object::Pad::VERSION of 0.48, to defend against possible API
    or ABI breakage. It is expected that as the API eventually stablises,
    this restriction can be removed.

SLOT ATTRIBUTES

 :LazyInit

       has $slot :LazyInit(NAME) ...;

    Declares that if the slot variable is read from before it has been
    otherwise initialised, then the named method will be called first to
    create an initial value for it. Initialisation by either by a :param
    declaration, explicit assignment into it, or the use of a :writer
    accessor will set the value for the slot and mean the lazy initialiser
    will not be invoked.

    After it has been invoked, the value is stored by the slot and
    thereafter it will behave as normal; subsequent reads will return the
    current value, and the initialiser method will not be invoked again.

    In order to avoid the possibility of accidental recursion when
    generating the value, it is recommended that the logic in the lazy
    initialisation method be as self-contained as possible; ideally not
    invoking any methods on $self, and only making use of other slots
    already declared before the slot being initialised. By placing the
    initialiser method immediately after the slot declaration, before any
    other slots, you can reduce the possilibity of getting stuck in such a
    manner.

       has $slot_zero :param;
    
       has $slot_one :LazyInit(_make_one);
       method _make_one {
          # we can safely use $slot_zero in here
       }
    
       has $slot_two :LazyInit(_make_two);
       method _make_two {
          # we can safely use $slot_zero and $slot_one
       }

AUTHOR

    Paul Evans <leonerd@leonerd.org.uk>

