1Class::Struct(3pm) Perl Programmers Reference Guide Class::Struct(3pm)
2
3
4
6 Class::Struct - declare struct-like datatypes as Perl classes
7
9 use Class::Struct;
10 # declare struct, based on array:
11 struct( CLASS_NAME => [ ELEMENT_NAME => ELEMENT_TYPE, ... ]);
12 # declare struct, based on hash:
13 struct( CLASS_NAME => { ELEMENT_NAME => ELEMENT_TYPE, ... });
14
15 package CLASS_NAME;
16 use Class::Struct;
17 # declare struct, based on array, implicit class name:
18 struct( ELEMENT_NAME => ELEMENT_TYPE, ... );
19
20 # Declare struct at compile time
21 use Class::Struct CLASS_NAME => [ELEMENT_NAME => ELEMENT_TYPE, ...];
22 use Class::Struct CLASS_NAME => {ELEMENT_NAME => ELEMENT_TYPE, ...};
23
24 # declare struct at compile time, based on array, implicit
25 # class name:
26 package CLASS_NAME;
27 use Class::Struct ELEMENT_NAME => ELEMENT_TYPE, ... ;
28
29 package Myobj;
30 use Class::Struct;
31 # declare struct with four types of elements:
32 struct( s => '$', a => '@', h => '%', c => 'My_Other_Class' );
33
34 $obj = new Myobj; # constructor
35
36 # scalar type accessor:
37 $element_value = $obj->s; # element value
38 $obj->s('new value'); # assign to element
39
40 # array type accessor:
41 $ary_ref = $obj->a; # reference to whole array
42 $ary_element_value = $obj->a(2); # array element value
43 $obj->a(2, 'new value'); # assign to array element
44
45 # hash type accessor:
46 $hash_ref = $obj->h; # reference to whole hash
47 $hash_element_value = $obj->h('x'); # hash element value
48 $obj->h('x', 'new value'); # assign to hash element
49
50 # class type accessor:
51 $element_value = $obj->c; # object reference
52 $obj->c->method(...); # call method of object
53 $obj->c(new My_Other_Class); # assign a new object
54
56 "Class::Struct" exports a single function, "struct". Given a list of
57 element names and types, and optionally a class name, "struct" creates
58 a Perl 5 class that implements a "struct-like" data structure.
59
60 The new class is given a constructor method, "new", for creating struct
61 objects.
62
63 Each element in the struct data has an accessor method, which is used
64 to assign to the element and to fetch its value. The default accessor
65 can be overridden by declaring a "sub" of the same name in the package.
66 (See Example 2.)
67
68 Each element's type can be scalar, array, hash, or class.
69
70 The "struct()" function
71 The "struct" function has three forms of parameter-list.
72
73 struct( CLASS_NAME => [ ELEMENT_LIST ]);
74 struct( CLASS_NAME => { ELEMENT_LIST });
75 struct( ELEMENT_LIST );
76
77 The first and second forms explicitly identify the name of the class
78 being created. The third form assumes the current package name as the
79 class name.
80
81 An object of a class created by the first and third forms is based on
82 an array, whereas an object of a class created by the second form is
83 based on a hash. The array-based forms will be somewhat faster and
84 smaller; the hash-based forms are more flexible.
85
86 The class created by "struct" must not be a subclass of another class
87 other than "UNIVERSAL".
88
89 It can, however, be used as a superclass for other classes. To
90 facilitate this, the generated constructor method uses a two-argument
91 blessing. Furthermore, if the class is hash-based, the key of each
92 element is prefixed with the class name (see Perl Cookbook, Recipe
93 13.12).
94
95 A function named "new" must not be explicitly defined in a class
96 created by "struct".
97
98 The ELEMENT_LIST has the form
99
100 NAME => TYPE, ...
101
102 Each name-type pair declares one element of the struct. Each element
103 name will be defined as an accessor method unless a method by that name
104 is explicitly defined; in the latter case, a warning is issued if the
105 warning flag (-w) is set.
106
107 Class Creation at Compile Time
108 "Class::Struct" can create your class at compile time. The main reason
109 for doing this is obvious, so your class acts like every other class in
110 Perl. Creating your class at compile time will make the order of
111 events similar to using any other class ( or Perl module ).
112
113 There is no significant speed gain between compile time and run time
114 class creation, there is just a new, more standard order of events.
115
116 Element Types and Accessor Methods
117 The four element types -- scalar, array, hash, and class -- are
118 represented by strings -- '$', '@', '%', and a class name -- optionally
119 preceded by a '*'.
120
121 The accessor method provided by "struct" for an element depends on the
122 declared type of the element.
123
124 Scalar ('$' or '*$')
125 The element is a scalar, and by default is initialized to "undef"
126 (but see "Initializing with new").
127
128 The accessor's argument, if any, is assigned to the element.
129
130 If the element type is '$', the value of the element (after
131 assignment) is returned. If the element type is '*$', a reference
132 to the element is returned.
133
134 Array ('@' or '*@')
135 The element is an array, initialized by default to "()".
136
137 With no argument, the accessor returns a reference to the element's
138 whole array (whether or not the element was specified as '@' or
139 '*@').
140
141 With one or two arguments, the first argument is an index
142 specifying one element of the array; the second argument, if
143 present, is assigned to the array element. If the element type is
144 '@', the accessor returns the array element value. If the element
145 type is '*@', a reference to the array element is returned.
146
147 As a special case, when the accessor is called with an array
148 reference as the sole argument, this causes an assignment of the
149 whole array element. The object reference is returned.
150
151 Hash ('%' or '*%')
152 The element is a hash, initialized by default to "()".
153
154 With no argument, the accessor returns a reference to the element's
155 whole hash (whether or not the element was specified as '%' or
156 '*%').
157
158 With one or two arguments, the first argument is a key specifying
159 one element of the hash; the second argument, if present, is
160 assigned to the hash element. If the element type is '%', the
161 accessor returns the hash element value. If the element type is
162 '*%', a reference to the hash element is returned.
163
164 As a special case, when the accessor is called with a hash
165 reference as the sole argument, this causes an assignment of the
166 whole hash element. The object reference is returned.
167
168 Class ('Class_Name' or '*Class_Name')
169 The element's value must be a reference blessed to the named class
170 or to one of its subclasses. The element is not initialized by
171 default.
172
173 The accessor's argument, if any, is assigned to the element. The
174 accessor will "croak" if this is not an appropriate object
175 reference.
176
177 If the element type does not start with a '*', the accessor returns
178 the element value (after assignment). If the element type starts
179 with a '*', a reference to the element itself is returned.
180
181 Initializing with "new"
182 "struct" always creates a constructor called "new". That constructor
183 may take a list of initializers for the various elements of the new
184 struct.
185
186 Each initializer is a pair of values: element name" => "value. The
187 initializer value for a scalar element is just a scalar value. The
188 initializer for an array element is an array reference. The initializer
189 for a hash is a hash reference.
190
191 The initializer for a class element is an object of the corresponding
192 class, or of one of it's subclasses, or a reference to a hash
193 containing named arguments to be passed to the element's constructor.
194
195 See Example 3 below for an example of initialization.
196
198 Example 1
199 Giving a struct element a class type that is also a struct is how
200 structs are nested. Here, "Timeval" represents a time (seconds and
201 microseconds), and "Rusage" has two elements, each of which is of
202 type "Timeval".
203
204 use Class::Struct;
205
206 struct( Rusage => {
207 ru_utime => 'Timeval', # user time used
208 ru_stime => 'Timeval', # system time used
209 });
210
211 struct( Timeval => [
212 tv_secs => '$', # seconds
213 tv_usecs => '$', # microseconds
214 ]);
215
216 # create an object:
217 my $t = Rusage->new(ru_utime=>Timeval->new(),
218 ru_stime=>Timeval->new());
219
220 # $t->ru_utime and $t->ru_stime are objects of type Timeval.
221 # set $t->ru_utime to 100.0 sec and $t->ru_stime to 5.0 sec.
222 $t->ru_utime->tv_secs(100);
223 $t->ru_utime->tv_usecs(0);
224 $t->ru_stime->tv_secs(5);
225 $t->ru_stime->tv_usecs(0);
226
227 Example 2
228 An accessor function can be redefined in order to provide
229 additional checking of values, etc. Here, we want the "count"
230 element always to be nonnegative, so we redefine the "count"
231 accessor accordingly.
232
233 package MyObj;
234 use Class::Struct;
235
236 # declare the struct
237 struct ( 'MyObj', { count => '$', stuff => '%' } );
238
239 # override the default accessor method for 'count'
240 sub count {
241 my $self = shift;
242 if ( @_ ) {
243 die 'count must be nonnegative' if $_[0] < 0;
244 $self->{'MyObj::count'} = shift;
245 warn "Too many args to count" if @_;
246 }
247 return $self->{'MyObj::count'};
248 }
249
250 package main;
251 $x = new MyObj;
252 print "\$x->count(5) = ", $x->count(5), "\n";
253 # prints '$x->count(5) = 5'
254
255 print "\$x->count = ", $x->count, "\n";
256 # prints '$x->count = 5'
257
258 print "\$x->count(-5) = ", $x->count(-5), "\n";
259 # dies due to negative argument!
260
261 Example 3
262 The constructor of a generated class can be passed a list of
263 element=>value pairs, with which to initialize the struct. If no
264 initializer is specified for a particular element, its default
265 initialization is performed instead. Initializers for non-existent
266 elements are silently ignored.
267
268 Note that the initializer for a nested class may be specified as an
269 object of that class, or as a reference to a hash of initializers
270 that are passed on to the nested struct's constructor.
271
272 use Class::Struct;
273
274 struct Breed =>
275 {
276 name => '$',
277 cross => '$',
278 };
279
280 struct Cat =>
281 [
282 name => '$',
283 kittens => '@',
284 markings => '%',
285 breed => 'Breed',
286 ];
287
288
289 my $cat = Cat->new( name => 'Socks',
290 kittens => ['Monica', 'Kenneth'],
291 markings => { socks=>1, blaze=>"white" },
292 breed => Breed->new(name=>'short-hair', cross=>1),
293 or: breed => {name=>'short-hair', cross=>1},
294 );
295
296 print "Once a cat called ", $cat->name, "\n";
297 print "(which was a ", $cat->breed->name, ")\n";
298 print "had 2 kittens: ", join(' and ', @{$cat->kittens}), "\n";
299
301 Modified by Damian Conway, 2001-09-10, v0.62.
302
303 Modified implicit construction of nested objects.
304 Now will also take an object ref instead of requiring a hash ref.
305 Also default initializes nested object attributes to undef, rather
306 than calling object constructor without args
307 Original over-helpfulness was fraught with problems:
308 * the class's constructor might not be called 'new'
309 * the class might not have a hash-like-arguments constructor
310 * the class might not have a no-argument constructor
311 * "recursive" data structures didn't work well:
312 package Person;
313 struct { mother => 'Person', father => 'Person'};
314
315 Modified by Casey West, 2000-11-08, v0.59.
316
317 Added the ability for compile time class creation.
318
319 Modified by Damian Conway, 1999-03-05, v0.58.
320
321 Added handling of hash-like arg list to class ctor.
322
323 Changed to two-argument blessing in ctor to support
324 derivation from created classes.
325
326 Added classname prefixes to keys in hash-based classes
327 (refer to "Perl Cookbook", Recipe 13.12 for rationale).
328
329 Corrected behaviour of accessors for '*@' and '*%' struct
330 elements. Package now implements documented behaviour when
331 returning a reference to an entire hash or array element.
332 Previously these were returned as a reference to a reference
333 to the element.
334
335 Renamed to "Class::Struct" and modified by Jim Miner, 1997-04-02.
336
337 members() function removed.
338 Documentation corrected and extended.
339 Use of struct() in a subclass prohibited.
340 User definition of accessor allowed.
341 Treatment of '*' in element types corrected.
342 Treatment of classes as element types corrected.
343 Class name to struct() made optional.
344 Diagnostic checks added.
345
346 Originally "Class::Template" by Dean Roehrich.
347
348 # Template.pm --- struct/member template builder
349 # 12mar95
350 # Dean Roehrich
351 #
352 # changes/bugs fixed since 28nov94 version:
353 # - podified
354 # changes/bugs fixed since 21nov94 version:
355 # - Fixed examples.
356 # changes/bugs fixed since 02sep94 version:
357 # - Moved to Class::Template.
358 # changes/bugs fixed since 20feb94 version:
359 # - Updated to be a more proper module.
360 # - Added "use strict".
361 # - Bug in build_methods, was using @var when @$var needed.
362 # - Now using my() rather than local().
363 #
364 # Uses perl5 classes to create nested data types.
365 # This is offered as one implementation of Tom Christiansen's
366 # "structs.pl" idea.
367
368
369
370perl v5.30.2 2020-03-27 Class::Struct(3pm)