File Coverage

blib/lib/Object/Pad/SlotAttr/LazyInit.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 13 13 100.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2021 -- leonerd@leonerd.org.uk
5              
6             package Object::Pad::SlotAttr::LazyInit 0.04;
7              
8 2     2   65051 use v5.14;
  2         15  
9 2     2   11 use warnings;
  2         4  
  2         57  
10              
11 2     2   515 use Object::Pad 0.50;
  2         9067  
  2         11  
12              
13             require XSLoader;
14             XSLoader::load( __PACKAGE__, our $VERSION );
15              
16             =head1 NAME
17              
18             C - lazily initialise C slots at first read
19              
20             =head1 SYNOPSIS
21              
22             use Object::Pad;
23             use Object::Pad::SlotAttr::LazyInit;
24              
25             class Item {
26             has $uuid :reader :param :LazyInit(_make_uuid);
27              
28             method _make_uuid {
29             require Data::GUID;
30             return Data::GUID->new->as_string;
31             }
32             }
33              
34             =head1 DESCRIPTION
35              
36             This module provides a third-party slot attribute for L-based
37             classes, which declares that the slot it is attached to has a lazy
38             initialisation method, which will be called the first time the slot's value
39             is read from.
40              
41             B The ability for L to take third-party slot attributes
42             is still new and highly experimental, and subject to much API change in
43             future. As a result, this module should be considered equally experimental.
44              
45             =head1 SLOT ATTRIBUTES
46              
47             =head2 :LazyInit
48              
49             has $slot :LazyInit(NAME) ...;
50              
51             Declares that if the slot variable is read from before it has been otherwise
52             initialised, then the named method will be called first to create an initial
53             value for it. Initialisation by either by a C<:param> declaration, explicit
54             assignment into it, or the use of a C<:writer> accessor will set the value for
55             the slot and mean the lazy initialiser will not be invoked.
56              
57             After it has been invoked, the value is stored by the slot and thereafter it
58             will behave as normal; subsequent reads will return the current value, and the
59             initialiser method will not be invoked again.
60              
61             In order to avoid the possibility of accidental recursion when generating the
62             value, it is recommended that the logic in the lazy initialisation method be
63             as self-contained as possible; ideally not invoking any methods on C<$self>,
64             and only making use of other slots already declared before the slot being
65             initialised. By placing the initialiser method immediately after the slot
66             declaration, before any other slots, you can reduce the possibility of getting
67             stuck in such a manner.
68              
69             has $slot_zero :param;
70              
71             has $slot_one :LazyInit(_make_one);
72             method _make_one {
73             # we can safely use $slot_zero in here
74             }
75              
76             has $slot_two :LazyInit(_make_two);
77             method _make_two {
78             # we can safely use $slot_zero and $slot_one
79             }
80              
81             =cut
82              
83             sub import
84             {
85 2     2   111 $^H{"Object::Pad::SlotAttr::LazyInit/LazyInit"}++;
86             }
87              
88             =head1 AUTHOR
89              
90             Paul Evans
91              
92             =cut
93              
94             0x55AA;