1Class::Tiny(3)        User Contributed Perl Documentation       Class::Tiny(3)
2
3
4

NAME

6       Class::Tiny - Minimalist class construction
7

VERSION

9       version 1.008
10

SYNOPSIS

12       In Person.pm:
13
14         package Person;
15
16         use Class::Tiny qw( name );
17
18         1;
19
20       In Employee.pm:
21
22         package Employee;
23         use parent 'Person';
24
25         use Class::Tiny qw( ssn ), {
26           timestamp => sub { time }   # attribute with default
27         };
28
29         1;
30
31       In example.pl:
32
33         use Employee;
34
35         my $obj = Employee->new( name => "Larry", ssn => "111-22-3333" );
36
37         # unknown attributes are ignored
38         my $obj = Employee->new( name => "Larry", OS => "Linux" );
39         # $obj->{OS} does not exist
40

DESCRIPTION

42       This module offers a minimalist class construction kit in around 120
43       lines of code.  Here is a list of features:
44
45       •   defines attributes via import arguments
46
47       •   generates read-write accessors
48
49       •   supports lazy attribute defaults
50
51       •   supports custom accessors
52
53       •   superclass provides a standard "new" constructor
54
55       •   "new" takes a hash reference or list of key/value pairs
56
57       •   "new" supports providing "BUILDARGS" to customize constructor
58           options
59
60       •   "new" calls "BUILD" for each class from parent to child
61
62       •   superclass provides a "DESTROY" method
63
64       •   "DESTROY" calls "DEMOLISH" for each class from child to parent
65
66       Multiple-inheritance is possible, with superclass order determined via
67       mro::get_linear_isa.
68
69       It uses no non-core modules for any recent Perl. On Perls older than
70       v5.10 it requires MRO::Compat. On Perls older than v5.14, it requires
71       Devel::GlobalDestruction.
72

USAGE

74   Defining attributes
75       Define attributes as a list of import arguments:
76
77           package Foo::Bar;
78
79           use Class::Tiny qw(
80               name
81               id
82               height
83               weight
84           );
85
86       For each attribute, a read-write accessor is created unless a
87       subroutine of that name already exists:
88
89           $obj->name;               # getter
90           $obj->name( "John Doe" ); # setter
91
92       Attribute names must be valid subroutine identifiers or an exception
93       will be thrown.
94
95       You can specify lazy defaults by defining attributes with a hash
96       reference.  Keys define attribute names and values are constants or
97       code references that will be evaluated when the attribute is first
98       accessed if no value has been set.  The object is passed as an argument
99       to a code reference.
100
101           package Foo::WithDefaults;
102
103           use Class::Tiny qw/name id/, {
104               title     => 'Peon',
105               skills    => sub { [] },
106               hire_date => sub { $_[0]->_build_hire_date },
107           };
108
109       When subclassing, if multiple accessors of the same name exist in
110       different classes, any default (or lack of default) is determined by
111       standard method resolution order.
112
113       To make your own custom accessors, just pre-declare the method name
114       before loading Class::Tiny:
115
116           package Foo::Bar;
117
118           use subs 'id';
119
120           use Class::Tiny qw( name id );
121
122           sub id { ... }
123
124       Even if you pre-declare a method name, you must include it in the
125       attribute list for Class::Tiny to register it as a valid attribute.
126
127       If you set a default for a custom accessor, your accessor will need to
128       retrieve the default and do something with it:
129
130           package Foo::Bar;
131
132           use subs 'id';
133
134           use Class::Tiny qw( name ), { id => sub { int(rand(2*31)) } };
135
136           sub id {
137               my $self = shift;
138               if (@_) {
139                   return $self->{id} = shift;
140               }
141               elsif ( exists $self->{id} ) {
142                   return $self->{id};
143               }
144               else {
145                   my $defaults =
146                       Class::Tiny->get_all_attribute_defaults_for( ref $self );
147                   return $self->{id} = $defaults->{id}->();
148               }
149           }
150
151   Class::Tiny::Object is your base class
152       If your class does not already inherit from some class, then
153       Class::Tiny::Object will be added to your @ISA to provide "new" and
154       "DESTROY".
155
156       If your class does inherit from something, then no additional
157       inheritance is set up.  If the parent subclasses Class::Tiny::Object,
158       then all is well.  If not, then you'll get accessors set up but no
159       constructor or destructor. Don't do that unless you really have a
160       special need for it.
161
162       Define subclasses as normal.  It's best to define them with base,
163       parent or superclass before defining attributes with Class::Tiny so the
164       @ISA array is already populated at compile-time:
165
166           package Foo::Bar::More;
167
168           use parent 'Foo::Bar';
169
170           use Class::Tiny qw( shoe_size );
171
172   Object construction
173       If your class inherits from Class::Tiny::Object (as it should if you
174       followed the advice above), it provides the "new" constructor for you.
175
176       Objects can be created with attributes given as a hash reference or as
177       a list of key/value pairs:
178
179           $obj = Foo::Bar->new( name => "David" );
180
181           $obj = Foo::Bar->new( { name => "David" } );
182
183       If a reference is passed as a single argument, it must be able to be
184       dereferenced as a hash or an exception is thrown.
185
186       Unknown attributes in the constructor arguments will be ignored.  Prior
187       to version 1.000, unknown attributes were an error, but this made it
188       harder for people to cleanly subclass Class::Tiny classes so this
189       feature was removed.
190
191       You can define a "BUILDARGS" method to change how arguments to new are
192       handled.  It will receive the constructor arguments as they were
193       provided and must return a hash reference of key/value pairs (or else
194       throw an exception).
195
196           sub BUILDARGS {
197              my $class = shift;
198              my $name = shift || "John Doe";
199              return { name => $name };
200            };
201
202            Foo::Bar->new( "David" );
203            Foo::Bar->new(); # "John Doe"
204
205       Unknown attributes returned from "BUILDARGS" will be ignored.
206
207   BUILD
208       If your class or any superclass defines a "BUILD" method, it will be
209       called by the constructor from the furthest parent class down to the
210       child class after the object has been created.
211
212       It is passed the constructor arguments as a hash reference.  The return
213       value is ignored.  Use "BUILD" for validation, checking required
214       attributes or setting default values that depend on other attributes.
215
216           sub BUILD {
217               my ($self, $args) = @_;
218
219               for my $req ( qw/name age/ ) {
220                   croak "$req attribute required" unless defined $self->$req;
221               }
222
223               croak "Age must be non-negative" if $self->age < 0;
224
225               $self->msg( "Hello " . $self->name );
226           }
227
228       The argument reference is a copy, so deleting elements won't affect
229       data in the original (but changes will be passed to other BUILD methods
230       in @ISA).
231
232   DEMOLISH
233       Class::Tiny provides a "DESTROY" method.  If your class or any
234       superclass defines a "DEMOLISH" method, they will be called from the
235       child class to the furthest parent class during object destruction.  It
236       is provided a single boolean argument indicating whether Perl is in
237       global destruction.  Return values are ignored.  Errors are caught and
238       rethrown.
239
240           sub DEMOLISH {
241               my ($self, $global_destruct) = @_;
242               $self->cleanup();
243           }
244
245   Introspection and internals
246       You can retrieve an unsorted list of valid attributes known to
247       Class::Tiny for a class and its superclasses with the
248       "get_all_attributes_for" class method.
249
250           my @attrs = Class::Tiny->get_all_attributes_for("Employee");
251           # returns qw/name ssn timestamp/
252
253       Likewise, a hash reference of all valid attributes and default values
254       (or code references) may be retrieved with the
255       "get_all_attribute_defaults_for" class method.  Any attributes without
256       a default will be "undef".
257
258           my $def = Class::Tiny->get_all_attribute_defaults_for("Employee");
259           # returns {
260           #   name => undef,
261           #   ssn => undef
262           #   timestamp => $coderef
263           # }
264
265       The "import" method uses two class methods, "prepare_class" and
266       "create_attributes" to set up the @ISA array and attributes.  Anyone
267       attempting to extend Class::Tiny itself should use these instead of
268       mocking up a call to "import".
269
270       When the first object is created, linearized @ISA, the valid attribute
271       list and various subroutine references are cached for speed.  Ensure
272       that all inheritance and methods are in place before creating objects.
273       (You don't want to be changing that once you create objects anyway,
274       right?)
275

RATIONALE

277   Why this instead of Object::Tiny or Class::Accessor or something else?
278       I wanted something so simple that it could potentially be used by core
279       Perl modules I help maintain (or hope to write), most of which either
280       use Class::Struct or roll-their-own OO framework each time.
281
282       Object::Tiny and Object::Tiny::RW were close to what I wanted, but
283       lacking some features I deemed necessary, and their maintainers have an
284       even more strict philosophy against feature creep than I have.
285
286       I also considered Class::Accessor, which has been around a long time
287       and is heavily used, but it, too, lacked features I wanted and did
288       things in ways I considered poor design.
289
290       I looked for something else on CPAN, but after checking a dozen class
291       creators I realized I could implement exactly what I wanted faster than
292       I could search CPAN for something merely sufficient.
293
294       In general, compared to most things on CPAN (other than Object::Tiny),
295       Class::Tiny is smaller in implementation and simpler in API.
296
297       Specifically, here is how Class::Tiny ("C::T") compares to Object::Tiny
298       ("O::T") and Class::Accessor ("C::A"):
299
300        FEATURE                            C::T    O::T      C::A
301        --------------------------------------------------------------
302        attributes defined via import      yes     yes       no
303        read/write accessors               yes     no        yes
304        lazy attribute defaults            yes     no        no
305        provides new                       yes     yes       yes
306        provides DESTROY                   yes     no        no
307        new takes either hashref or list   yes     no (list) no (hash)
308        Moo(se)-like BUILD/DEMOLISH        yes     no        no
309        Moo(se)-like BUILDARGS             yes     no        no
310        no extraneous methods via @ISA     yes     yes       no
311
312   Why this instead of Moose or Moo?
313       Moose and Moo are both excellent OO frameworks.  Moose offers a
314       powerful meta-object protocol (MOP), but is slow to start up and has
315       about 30 non-core dependencies including XS modules.  Moo is faster to
316       start up and has about 10 pure Perl dependencies but provides no true
317       MOP, relying instead on its ability to transparently upgrade Moo to
318       Moose when Moose's full feature set is required.
319
320       By contrast, Class::Tiny has no MOP and has zero non-core dependencies
321       for Perls in the support window.  It has far less code, less complexity
322       and no learning curve. If you don't need or can't afford what Moo or
323       Moose offer, this is intended to be a reasonable fallback.
324
325       That said, Class::Tiny offers Moose-like conventions for things like
326       "BUILD" and "DEMOLISH" for some minimal interoperability and an easier
327       upgrade path.
328

AUTHOR

330       David Golden <dagolden@cpan.org>
331

CONTRIBUTORS

333       •   Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
334
335       •   David Golden <xdg@xdg.me>
336
337       •   Gelu Lupas <gelu@devnull.ro>
338
339       •   Karen Etheridge <ether@cpan.org>
340
341       •   Matt S Trout <mstrout@cpan.org>
342
343       •   Olivier Mengué <dolmen@cpan.org>
344
345       •   Toby Inkster <tobyink@cpan.org>
346
348       This software is Copyright (c) 2013 by David Golden.
349
350       This is free software, licensed under:
351
352         The Apache License, Version 2.0, January 2004
353
354
355
356perl v5.38.0                      2023-07-20                    Class::Tiny(3)
Impressum