1NAME
2
3 Struct::Dumb - make simple lightweight record-like structures
4
5SYNOPSIS
6
7 use Struct::Dumb;
8
9 struct Point => [qw( x y )];
10
11 my $point = Point(10, 20);
12
13 printf "Point is at (%d, %d)\n", $point->x, $point->y;
14
15 $point->y = 30;
16 printf "Point is now at (%d, %d)\n", $point->x, $point->y;
17
18
19 struct Point3D => [qw( x y z )], named_constructor => 1;
20
21 my $point3d = Point3D( z => 12, x => 100, y => 50 );
22
23 printf "Point3d's height is %d\n", $point3d->z;
24
25
26 struct Point3D => [qw( x y z )], predicate => "is_Point3D";
27
28 my $point3d = Point3D( 1, 2, 3 );
29
30 printf "This is a Point3D\n" if is_Point3D( $point3d );
31
32
33 use Struct::Dumb qw( -named_constructors )
34
35 struct Point3D => [qw( x y z )];
36
37 my $point3d = Point3D( x => 100, z => 12, y => 50 );
38
39DESCRIPTION
40
41 Struct::Dumb creates record-like structure types, similar to the struct
42 keyword in C, C++ or C#, or Record in Pascal. An invocation of this
43 module will create a construction function which returns new object
44 references with the given field values. These references all respond to
45 lvalue methods that access or modify the values stored.
46
47 It's specifically and intentionally not meant to be an object class.
48 You cannot subclass it. You cannot provide additional methods. You
49 cannot apply roles or mixins or metaclasses or traits or antlers or
50 whatever else is in fashion this week.
51
52 On the other hand, it is tiny, creates cheap lightweight array-backed
53 structures, uses nothing outside of core. It's intended simply to be a
54 slightly nicer way to store data structures, where otherwise you might
55 be tempted to abuse a hash, complete with the risk of typoing key
56 names. The constructor will croak if passed the wrong number of
57 arguments, as will attempts to refer to fields that don't exist.
58 Accessor-mutators will croak if invoked with arguments. (This helps
59 detect likely bugs such as accidentally passing in the new value as an
60 argument, or attempting to invoke a stored CODE reference by passing
61 argument values directly to the accessor.)
62
63 $ perl -E 'use Struct::Dumb; struct Point => [qw( x y )]; Point(30)'
64 usage: main::Point($x, $y) at -e line 1
65
66 $ perl -E 'use Struct::Dumb; struct Point => [qw( x y )]; Point(10,20)->z'
67 main::Point does not have a 'z' field at -e line 1
68
69 $ perl -E 'use Struct::Dumb; struct Point => [qw( x y )]; Point(1,2)->x(3)'
70 main::Point->x invoked with arguments at -e line 1.
71
72 Objects in this class are (currently) backed by an ARRAY reference
73 store, though this is an internal implementation detail and should not
74 be relied on by using code. Attempting to dereference the object as an
75 ARRAY will throw an exception.
76
77 CONSTRUCTOR FORMS
78
79 The struct and readonly_struct declarations create two different kinds
80 of constructor function, depending on the setting of the
81 named_constructor option. When false, the constructor takes positional
82 values in the same order as the fields were declared. When true, the
83 constructor takes a key/value pair list in no particular order, giving
84 the value of each named field.
85
86 This option can be specified to the struct and readonly_struct
87 functions. It defaults to false, but it can be set on a per-package
88 basis to default true by supplying the -named_constructors option on
89 the use statement.
90
91 When using named constructors, individual fields may be declared as
92 being optional. By preceeding the field name with a ? character, the
93 constructor is instructed not to complain if a named parameter is not
94 given for that field; instead it will be set to undef.
95
96 struct Person => [qw( name age ?address )],
97 named_constructor => 1;
98
99 my $bob = Person( name => "Bob", age => 20 );
100 # This is valid because 'address' is marked as optional
101
102FUNCTIONS
103
104 struct
105
106 struct $name => [ @fieldnames ],
107 named_constructor => (1|0),
108 predicate => "is_$name";
109
110 Creates a new structure type. This exports a new function of the type's
111 name into the caller's namespace. Invoking this function returns a new
112 instance of a type that implements those field names, as accessors and
113 mutators for the fields.
114
115 Takes the following options:
116
117 named_constructor => BOOL
118
119 Determines whether the structure will take positional or named
120 arguments.
121
122 predicate => STR
123
124 If defined, gives the name of a second function to export to the
125 caller's namespace. This function will be a type test predicate; that
126 is, a function that takes a single argmuent, and returns true
127 if-and-only-if that argument is an instance of this structure type.
128
129 readonly_struct
130
131 readonly_struct $name => [ @fieldnames ],
132 ...
133
134 Similar to "struct", but instances of this type are immutable once
135 constructed. The field accessor methods will not be marked with the
136 :lvalue attribute.
137
138 Takes the same options as "struct".
139
140DATA::DUMP FILTER
141
142 Since version 0.10.
143
144 If Data::Dump is loaded, an extra filter is applied so that struct
145 instances are printed in a format matching that which would construct
146 them.
147
148 struct Colour => [qw( red green blue )];
149
150 use Data::Dump;
151
152 my %hash = ( col => Colour( 0.8, 0.5, 0.2 ) );
153 Data::Dump::dd \%hash;
154
155 # prints {col => main::Colour(0.8, 0.5, 0.2)}
156
157NOTES
158
159 Allowing ARRAY dereference
160
161 The way that forbidding access to instances as if they were ARRAY
162 references is currently implemented uses an internal method on the
163 generated structure class called _forbid_arrayification. If special
164 circumstances require that this exception mechanism be bypassed, the
165 method can be overloaded with an empty sub {} body, allowing the struct
166 instances in that class to be accessed like normal ARRAY references.
167 For good practice this should be limited by a local override.
168
169 For example, Devel::Cycle needs to access the instances as plain ARRAY
170 references so it can walk the data structure looking for reference
171 cycles.
172
173 use Devel::Cycle;
174
175 {
176 no warnings 'redefine';
177 local *Point::_forbid_arrayification = sub {};
178
179 memory_cycle_ok( $point );
180 }
181
182TODO
183
184 * Consider adding an coerce_hash option, giving name of another
185 function to convert structs to key/value pairs, or a HASH ref.
186
187AUTHOR
188
189 Paul Evans <leonerd@leonerd.org.uk>
190
191