← Index
NYTProf Performance Profile   « block view • line view • sub view »
For ddd2.pl
  Run on Tue May 25 16:52:24 2010
Reported on Tue May 25 16:56:57 2010

File /project/perl/lib/Class/Accessor.pm
Statements Executed 1958
Statement Execution Time 28.0ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
4633218.3ms232msClass::Accessor::::__ANON__[:395]Class::Accessor::__ANON__[:395]
6114.59ms6.29msClass::Accessor::::_mk_accessorsClass::Accessor::_mk_accessors
15221.48ms1.48msClass::Accessor::::newClass::Accessor::new
3011527µs527µsClass::Accessor::::accessor_name_forClass::Accessor::accessor_name_for
3011499µs499µsClass::Accessor::::mutator_name_forClass::Accessor::mutator_name_for
1722410µs410µsClass::Accessor::::make_accessorClass::Accessor::make_accessor
666315µs6.60msClass::Accessor::::mk_accessorsClass::Accessor::mk_accessors
0000s0sClass::Accessor::::BEGINClass::Accessor::BEGIN
0000s0sClass::Accessor::::__ANON__[:422]Class::Accessor::__ANON__[:422]
0000s0sClass::Accessor::::__ANON__[:449]Class::Accessor::__ANON__[:449]
0000s0sClass::Accessor::::_carpClass::Accessor::_carp
0000s0sClass::Accessor::::_croakClass::Accessor::_croak
0000s0sClass::Accessor::::best_practice_accessor_name_forClass::Accessor::best_practice_accessor_name_for
0000s0sClass::Accessor::::best_practice_mutator_name_forClass::Accessor::best_practice_mutator_name_for
0000s0sClass::Accessor::::follow_best_practiceClass::Accessor::follow_best_practice
0000s0sClass::Accessor::::getClass::Accessor::get
0000s0sClass::Accessor::::make_ro_accessorClass::Accessor::make_ro_accessor
0000s0sClass::Accessor::::make_wo_accessorClass::Accessor::make_wo_accessor
0000s0sClass::Accessor::::mk_ro_accessorsClass::Accessor::mk_ro_accessors
0000s0sClass::Accessor::::mk_wo_accessorsClass::Accessor::mk_wo_accessors
0000s0sClass::Accessor::::setClass::Accessor::set
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Class::Accessor;
215µsrequire 5.00502;
33333µs124µsuse strict;
# spent 24µs making 1 call to strict::import
415µs$Class::Accessor::VERSION = '0.30';
5
6=head1 NAME
7
8 Class::Accessor - Automated accessor generation
9
10=head1 SYNOPSIS
11
12 package Employee;
13 use base qw(Class::Accessor);
14 Employee->mk_accessors(qw(name role salary));
15
16 # Meanwhile, in a nearby piece of code!
17 # Class::Accessor provides new().
18 my $mp = Foo->new({ name => "Marty", role => "JAPH" });
19
20 my $job = $mp->role; # gets $mp->{role}
21 $mp->salary(400000); # sets $mp->{salary} = 400000 (I wish)
22
23 # like my @info = @{$mp}{qw(name role)}
24 my @info = $mp->get(qw(name role));
25
26 # $mp->{salary} = 400000
27 $mp->set('salary', 400000);
28
29
30=head1 DESCRIPTION
31
32This module automagically generates accessors/mutators for your class.
33
34Most of the time, writing accessors is an exercise in cutting and
35pasting. You usually wind up with a series of methods like this:
36
37 sub name {
38 my $self = shift;
39 if(@_) {
40 $self->{name} = $_[0];
41 }
42 return $self->{name};
43 }
44
45 sub salary {
46 my $self = shift;
47 if(@_) {
48 $self->{salary} = $_[0];
49 }
50 return $self->{salary};
51 }
52
53 # etc...
54
55One for each piece of data in your object. While some will be unique,
56doing value checks and special storage tricks, most will simply be
57exercises in repetition. Not only is it Bad Style to have a bunch of
58repetitious code, but its also simply not lazy, which is the real
59tragedy.
60
61If you make your module a subclass of Class::Accessor and declare your
62accessor fields with mk_accessors() then you'll find yourself with a
63set of automatically generated accessors which can even be
64customized!
65
66The basic set up is very simple:
67
68 package My::Class;
69 use base qw(Class::Accessor);
70 My::Class->mk_accessors( qw(foo bar car) );
71
72Done. My::Class now has simple foo(), bar() and car() accessors
73defined.
74
75=head2 What Makes This Different?
76
77What makes this module special compared to all the other method
78generating modules (L<"SEE ALSO">)? By overriding the get() and set()
79methods you can alter the behavior of the accessors class-wide. Also,
80the accessors are implemented as closures which should cost a bit less
81memory than most other solutions which generate a new method for each
82accessor.
83
84
85=head1 METHODS
86
87=head2 new
88
89 my $obj = Class->new;
90 my $obj = $other_obj->new;
91
92 my $obj = Class->new(\%fields);
93 my $obj = $other_obj->new(\%fields);
94
95Class::Accessor provides a basic constructor. It generates a
96hash-based object and can be called as either a class method or an
97object method.
98
99It takes an optional %fields hash which is used to initialize the
100object (handy if you use read-only accessors). The fields of the hash
101correspond to the names of your accessors, so...
102
103 package Foo;
104 use base qw(Class::Accessor);
105 Foo->mk_accessors('foo');
106
107 my $obj = Class->new({ foo => 42 });
108 print $obj->foo; # 42
109
110however %fields can contain anything, new() will shove them all into
111your object. Don't like it? Override it.
112
113=cut
114
115
# spent 1.48ms within Class::Accessor::new which was called 15 times, avg 99µs/call: # 10 times (1.16ms+0s) by Class::DBI::Column::new at line 52 of Class/DBI/Column.pm, avg 116µs/call # 5 times (320µs+0s) by Class::DBI::Relationship::_init at line 24 of Class/DBI/Relationship.pm, avg 64µs/call
sub new {
116601.52ms my($proto, $fields) = @_;
117 my($class) = ref $proto || $proto;
118
119 $fields = {} unless defined $fields;
120
121 # make a copy of $fields.
122 bless {%$fields}, $class;
123}
124
125=head2 mk_accessors
126
127 Class->mk_accessors(@fields);
128
129This creates accessor/mutator methods for each named field given in
130@fields. Foreach field in @fields it will generate two accessors.
131One called "field()" and the other called "_field_accessor()". For
132example:
133
134 # Generates foo(), _foo_accessor(), bar() and _bar_accessor().
135 Class->mk_accessors(qw(foo bar));
136
137See L<CAVEATS AND TRICKS/"Overriding autogenerated accessors">
138for details.
139
140=cut
141
142
# spent 6.60ms (315µs+6.29) within Class::Accessor::mk_accessors which was called 6 times, avg 1.10ms/call: # once (53µs+1.43ms) by base::import at line 35 of Class/DBI/Query.pm # once (55µs+1.29ms) by base::import at line 16 of Class/DBI/Plugin/Pager.pm # once (57µs+1.06ms) by base::import at line 32 of Class/DBI/Column.pm # once (48µs+1.01ms) by base::import at line 8 of Class/DBI/Relationship.pm # once (51µs+854µs) by Class::DBI::_require_class at line 83 of Class/DBI/Search/Basic.pm # once (51µs+640µs) by base::import at line 5 of Data/Page.pm
sub mk_accessors {
14312297µs my($self, @fields) = @_;
144
145 $self->_mk_accessors('rw', @fields);
# spent 6.29ms making 6 calls to Class::Accessor::_mk_accessors, avg 1.05ms/call
146}
147
148
149{
15041.90ms1115µs no strict 'refs';
# spent 115µs making 1 call to strict::unimport
151
152
# spent 6.29ms (4.59+1.70) within Class::Accessor::_mk_accessors which was called 6 times, avg 1.05ms/call: # 6 times (4.59ms+1.70ms) by Class::Accessor::mk_accessors at line 145, avg 1.05ms/call
sub _mk_accessors {
15330315µs my($self, $access, @fields) = @_;
154 my $class = ref $self || $self;
155 my $ra = $access eq 'rw' || $access eq 'ro';
156 my $wa = $access eq 'rw' || $access eq 'wo';
157
158 foreach my $field (@fields) {
1591201.97ms30527µs my $accessor_name = $self->accessor_name_for($field);
# spent 527µs making 30 calls to Class::Accessor::accessor_name_for, avg 18µs/call
160 my $mutator_name = $self->mutator_name_for($field);
# spent 499µs making 30 calls to Class::Accessor::mutator_name_for, avg 17µs/call
161 if( $accessor_name eq 'DESTROY' or $mutator_name eq 'DESTROY' ) {
162 $self->_carp("Having a data accessor named DESTROY in '$class' is unwise.");
163 }
1641201.51ms if ($accessor_name eq $mutator_name) {
165 my $accessor;
166 if ($ra && $wa) {
# spent 315µs making 14 calls to Class::Accessor::Fast::make_accessor, avg 23µs/call # spent 202µs making 9 calls to Class::Accessor::Chained::Fast::make_accessor, avg 22µs/call # spent 155µs making 7 calls to Class::Accessor::make_accessor, avg 22µs/call
167 $accessor = $self->make_accessor($field);
168 } elsif ($ra) {
169 $accessor = $self->make_ro_accessor($field);
170 } else {
171 $accessor = $self->make_wo_accessor($field);
172 }
173 unless (defined &{"${class}::$accessor_name"}) {
174 *{"${class}::$accessor_name"} = $accessor;
175 }
17660507µs if ($accessor_name eq $field) {
177 # the old behaviour
178 my $alias = "_${field}_accessor";
179 *{"${class}::$alias"} = $accessor unless defined &{"${class}::$alias"};
180 }
181 } else {
182 if ($ra and not defined &{"${class}::$accessor_name"}) {
183 *{"${class}::$accessor_name"} = $self->make_ro_accessor($field);
184 }
185 if ($wa and not defined &{"${class}::$mutator_name"}) {
186 *{"${class}::$mutator_name"} = $self->make_wo_accessor($field);
187 }
188 }
189 }
190 }
191
192 sub follow_best_practice {
193 my($self) = @_;
194 my $class = ref $self || $self;
195 *{"${class}::accessor_name_for"} = \&best_practice_accessor_name_for;
196 *{"${class}::mutator_name_for"} = \&best_practice_mutator_name_for;
197 }
198
199}
200
201=head2 mk_ro_accessors
202
203 Class->mk_ro_accessors(@read_only_fields);
204
205Same as mk_accessors() except it will generate read-only accessors
206(ie. true accessors). If you attempt to set a value with these
207accessors it will throw an exception. It only uses get() and not
208set().
209
210 package Foo;
211 use base qw(Class::Accessor);
212 Class->mk_ro_accessors(qw(foo bar));
213
214 # Let's assume we have an object $foo of class Foo...
215 print $foo->foo; # ok, prints whatever the value of $foo->{foo} is
216 $foo->foo(42); # BOOM! Naughty you.
217
218
219=cut
220
221sub mk_ro_accessors {
222 my($self, @fields) = @_;
223
224 $self->_mk_accessors('ro', @fields);
225}
226
227=head2 mk_wo_accessors
228
229 Class->mk_wo_accessors(@write_only_fields);
230
231Same as mk_accessors() except it will generate write-only accessors
232(ie. mutators). If you attempt to read a value with these accessors
233it will throw an exception. It only uses set() and not get().
234
235B<NOTE> I'm not entirely sure why this is useful, but I'm sure someone
236will need it. If you've found a use, let me know. Right now its here
237for orthoginality and because its easy to implement.
238
239 package Foo;
240 use base qw(Class::Accessor);
241 Class->mk_wo_accessors(qw(foo bar));
242
243 # Let's assume we have an object $foo of class Foo...
244 $foo->foo(42); # OK. Sets $self->{foo} = 42
245 print $foo->foo; # BOOM! Can't read from this accessor.
246
247=cut
248
249sub mk_wo_accessors {
250 my($self, @fields) = @_;
251
252 $self->_mk_accessors('wo', @fields);
253}
254
255=head1 DETAILS
256
257An accessor generated by Class::Accessor looks something like
258this:
259
260 # Your foo may vary.
261 sub foo {
262 my($self) = shift;
263 if(@_) { # set
264 return $self->set('foo', @_);
265 }
266 else {
267 return $self->get('foo');
268 }
269 }
270
271Very simple. All it does is determine if you're wanting to set a
272value or get a value and calls the appropriate method.
273Class::Accessor provides default get() and set() methods which
274your class can override. They're detailed later.
275
276=head2 follow_best_practice
277
278In Damian's Perl Best Practices book he recommends separate get and set methods
279with the prefix set_ and get_ to make it explicit what you intend to do. If you
280want to create those accessor methods instead of the default ones, call:
281
282 __PACKAGE__->follow_best_practice
283
284=head2 accessor_name_for / mutator_name_for
285
286You may have your own crazy ideas for the names of the accessors, so you can
287make those happen by overriding C<accessor_name_for> and C<mutator_name_for> in
288your subclass. (I copied that idea from Class::DBI.)
289
290=cut
291
292sub best_practice_accessor_name_for {
293 my ($class, $field) = @_;
294 return "get_$field";
295}
296
297sub best_practice_mutator_name_for {
298 my ($class, $field) = @_;
299 return "set_$field";
300}
301
302
# spent 527µs within Class::Accessor::accessor_name_for which was called 30 times, avg 18µs/call: # 30 times (527µs+0s) by Class::Accessor::_mk_accessors at line 159, avg 18µs/call
sub accessor_name_for {
30360646µs my ($class, $field) = @_;
304 return $field;
305}
306
307
# spent 499µs within Class::Accessor::mutator_name_for which was called 30 times, avg 17µs/call: # 30 times (499µs+0s) by Class::Accessor::_mk_accessors at line 160, avg 17µs/call
sub mutator_name_for {
30860555µs my ($class, $field) = @_;
309 return $field;
310}
311
312=head2 Modifying the behavior of the accessor
313
314Rather than actually modifying the accessor itself, it is much more
315sensible to simply override the two key methods which the accessor
316calls. Namely set() and get().
317
318If you -really- want to, you can override make_accessor().
319
320=head2 set
321
322 $obj->set($key, $value);
323 $obj->set($key, @values);
324
325set() defines how generally one stores data in the object.
326
327override this method to change how data is stored by your accessors.
328
329=cut
330
331sub set {
332 my($self, $key) = splice(@_, 0, 2);
333
334 if(@_ == 1) {
335 $self->{$key} = $_[0];
336 }
337 elsif(@_ > 1) {
338 $self->{$key} = [@_];
339 }
340 else {
341 $self->_croak("Wrong number of arguments received");
342 }
343}
344
345=head2 get
346
347 $value = $obj->get($key);
348 @values = $obj->get(@keys);
349
350get() defines how data is retreived from your objects.
351
352override this method to change how it is retreived.
353
354=cut
355
356sub get {
357 my $self = shift;
358
359 if(@_ == 1) {
360 return $self->{$_[0]};
361 }
362 elsif( @_ > 1 ) {
363 return @{$self}{@_};
364 }
365 else {
366 $self->_croak("Wrong number of arguments received");
367 }
368}
369
370=head2 make_accessor
371
372 $accessor = Class->make_accessor($field);
373
374Generates a subroutine reference which acts as an accessor for the given
375$field. It calls get() and set().
376
377If you wish to change the behavior of your accessors, try overriding
378get() and set() before you start mucking with make_accessor().
379
380=cut
381
382
# spent 410µs within Class::Accessor::make_accessor which was called 17 times, avg 24µs/call: # 10 times (255µs+0s) by Class::DBI::_mk_column_accessors at line 359 of Class/DBI.pm, avg 26µs/call # 7 times (155µs+0s) by Class::Accessor::_mk_accessors at line 166, avg 22µs/call
sub make_accessor {
38334501µs my ($class, $field) = @_;
384
385 # Build a closure around $field.
386
# spent 232ms (18.3+214) within Class::Accessor::__ANON__[/project/perl/lib/Class/Accessor.pm:395] which was called 463 times, avg 501µs/call: # 461 times (18.2ms+202ms) by main::RUNTIME at line 8 of ddd2.pl, avg 477µs/call # once (40µs+11.3ms) by main::RUNTIME at line 10 of ddd2.pl # once (39µs+419µs) by Class::DBI::_flesh at line 857 of Class/DBI.pm
return sub {
3879264.93ms my $self = shift;
388
38946312.7ms if(@_) {
390 return $self->set($field, @_);
391 }
392 else {
393 return $self->get($field);
# spent 214ms making 463 calls to Class::DBI::get, avg 461µs/call, recursion: max depth 1, time 419µs
394 }
395 };
396}
397
398=head2 make_ro_accessor
399
400 $read_only_accessor = Class->make_ro_accessor($field);
401
402Generates a subroutine refrence which acts as a read-only accessor for
403the given $field. It only calls get().
404
405Override get() to change the behavior of your accessors.
406
407=cut
408
409sub make_ro_accessor {
410 my($class, $field) = @_;
411
412 return sub {
413 my $self = shift;
414
415 if (@_) {
416 my $caller = caller;
417 $self->_croak("'$caller' cannot alter the value of '$field' on objects of class '$class'");
418 }
419 else {
420 return $self->get($field);
421 }
422 };
423}
424
425=head2 make_wo_accessor
426
427 $read_only_accessor = Class->make_wo_accessor($field);
428
429Generates a subroutine refrence which acts as a write-only accessor
430(mutator) for the given $field. It only calls set().
431
432Override set() to change the behavior of your accessors.
433
434=cut
435
436sub make_wo_accessor {
437 my($class, $field) = @_;
438
439 return sub {
440 my $self = shift;
441
442 unless (@_) {
443 my $caller = caller;
444 $self->_croak("'$caller' cannot access the value of '$field' on objects of class '$class'");
445 }
446 else {
447 return $self->set($field, @_);
448 }
449 };
450}
451
452=head1 EXCEPTIONS
453
454If something goes wrong Class::Accessor will warn or die by calling Carp::carp
455or Carp::croak. If you don't like this you can override _carp() and _croak() in
456your subclass and do whatever else you want.
457
458=cut
459
4603297µsuse Carp ();
461
462sub _carp {
463 my ($self, $msg) = @_;
464 Carp::carp($msg || $self);
465 return;
466}
467
468sub _croak {
469 my ($self, $msg) = @_;
470 Carp::croak($msg || $self);
471 return;
472}
473
474=head1 EFFICIENCY
475
476Class::Accessor does not employ an autoloader, thus it is much faster
477than you'd think. Its generated methods incur no special penalty over
478ones you'd write yourself.
479
480Here are Schwern's results of benchmarking Class::Accessor,
481Class::Accessor::Fast, a hand-written accessor, and direct hash access.
482
483 Benchmark: timing 500000 iterations of By Hand - get, By Hand - set,
484 C::A - get, C::A - set, C::A::Fast - get, C::A::Fast - set,
485 Direct - get, Direct - set...
486
487 By Hand - get: 4 wallclock secs ( 5.09 usr + 0.00 sys = 5.09 CPU)
488 @ 98231.83/s (n=500000)
489 By Hand - set: 5 wallclock secs ( 6.06 usr + 0.00 sys = 6.06 CPU)
490 @ 82508.25/s (n=500000)
491 C::A - get: 9 wallclock secs ( 9.83 usr + 0.01 sys = 9.84 CPU)
492 @ 50813.01/s (n=500000)
493 C::A - set: 11 wallclock secs ( 9.95 usr + 0.00 sys = 9.95 CPU)
494 @ 50251.26/s (n=500000)
495 C::A::Fast - get: 6 wallclock secs ( 4.88 usr + 0.00 sys = 4.88 CPU)
496 @ 102459.02/s (n=500000)
497 C::A::Fast - set: 6 wallclock secs ( 5.83 usr + 0.00 sys = 5.83 CPU)
498 @ 85763.29/s (n=500000)
499 Direct - get: 0 wallclock secs ( 0.89 usr + 0.00 sys = 0.89 CPU)
500 @ 561797.75/s (n=500000)
501 Direct - set: 2 wallclock secs ( 0.87 usr + 0.00 sys = 0.87 CPU)
502 @ 574712.64/s (n=500000)
503
504So Class::Accessor::Fast is just as fast as one you'd write yourself
505while Class::Accessor is twice as slow, a price paid for flexibility.
506Direct hash access is about six times faster, but provides no
507encapsulation and no flexibility.
508
509Of course, its not as simple as saying "Class::Accessor is twice as
510slow as one you write yourself". These are benchmarks for the
511simplest possible accessor, if your accessors do any sort of
512complicated work (such as talking to a database or writing to a file)
513the time spent doing that work will quickly swamp the time spend just
514calling the accessor. In that case, Class::Accessor and the ones you
515write will tend to be just as fast.
516
517
518=head1 EXAMPLES
519
520Here's an example of generating an accessor for every public field of
521your class.
522
523 package Altoids;
524
525 use base qw(Class::Accessor Class::Fields);
526 use fields qw(curiously strong mints);
527 Altoids->mk_accessors( Altoids->show_fields('Public') );
528
529 sub new {
530 my $proto = shift;
531 my $class = ref $proto || $proto;
532 return fields::new($class);
533 }
534
535 my Altoids $tin = Altoids->new;
536
537 $tin->curiously('Curiouser and curiouser');
538 print $tin->{curiously}; # prints 'Curiouser and curiouser'
539
540
541 # Subclassing works, too.
542 package Mint::Snuff;
543 use base qw(Altoids);
544
545 my Mint::Snuff $pouch = Mint::Snuff->new;
546 $pouch->strong('Blow your head off!');
547 print $pouch->{strong}; # prints 'Blow your head off!'
548
549
550Here's a simple example of altering the behavior of your accessors.
551
552 package Foo;
553 use base qw(Class::Accessor);
554 Foo->mk_accessor(qw(this that up down));
555
556 sub get {
557 my $self = shift;
558
559 # Note every time someone gets some data.
560 print STDERR "Getting @_\n";
561
562 $self->SUPER::get(@_);
563 }
564
565 sub set {
566 my ($self, $key) = splice(@_, 0, 2);
567
568 # Note every time someone sets some data.
569 print STDERR "Setting $key to @_\n";
570
571 $self->SUPER::set($key, @_);
572 }
573
574
575=head1 CAVEATS AND TRICKS
576
577Class::Accessor has to do some internal wackiness to get its
578job done quickly and efficiently. Because of this, there's a few
579tricks and traps one must know about.
580
581Hey, nothing's perfect.
582
583=head2 Don't make a field called DESTROY
584
585This is bad. Since DESTROY is a magical method it would be bad for us
586to define an accessor using that name. Class::Accessor will
587carp if you try to use it with a field named "DESTROY".
588
589=head2 Overriding autogenerated accessors
590
591You may want to override the autogenerated accessor with your own, yet
592have your custom accessor call the default one. For instance, maybe
593you want to have an accessor which checks its input. Normally, one
594would expect this to work:
595
596 package Foo;
597 use base qw(Class::Accessor);
598 Foo->mk_accessors(qw(email this that whatever));
599
600 # Only accept addresses which look valid.
601 sub email {
602 my($self) = shift;
603 my($email) = @_;
604
605 if( @_ ) { # Setting
606 require Email::Valid;
607 unless( Email::Valid->address($email) ) {
608 carp("$email doesn't look like a valid address.");
609 return;
610 }
611 }
612
613 return $self->SUPER::email(@_);
614 }
615
616There's a subtle problem in the last example, and its in this line:
617
618 return $self->SUPER::email(@_);
619
620If we look at how Foo was defined, it called mk_accessors() which
621stuck email() right into Foo's namespace. There *is* no
622SUPER::email() to delegate to! Two ways around this... first is to
623make a "pure" base class for Foo. This pure class will generate the
624accessors and provide the necessary super class for Foo to use:
625
626 package Pure::Organic::Foo;
627 use base qw(Class::Accessor);
628 Pure::Organic::Foo->mk_accessors(qw(email this that whatever));
629
630 package Foo;
631 use base qw(Pure::Organic::Foo);
632
633And now Foo::email() can override the generated
634Pure::Organic::Foo::email() and use it as SUPER::email().
635
636This is probably the most obvious solution to everyone but me.
637Instead, what first made sense to me was for mk_accessors() to define
638an alias of email(), _email_accessor(). Using this solution,
639Foo::email() would be written with:
640
641 return $self->_email_accessor(@_);
642
643instead of the expected SUPER::email().
644
645
646=head1 AUTHORS
647
648Copyright 2005 Marty Pauley <marty+perl@kasei.com>
649
650This program is free software; you can redistribute it and/or modify it under
651the same terms as Perl itself. That means either (a) the GNU General Public
652License or (b) the Artistic License.
653
654=head2 ORIGINAL AUTHOR
655
656Michael G Schwern <schwern@pobox.com>
657
658=head2 THANKS
659
660Liz, for performance tweaks.
661
662Tels, for his big feature request/bug report.
663
664
665=head1 SEE ALSO
666
667L<Class::Accessor::Fast>
668
669These are some modules which do similar things in different ways
670L<Class::Struct>, L<Class::Methodmaker>, L<Class::Generate>,
671L<Class::Class>, L<Class::Contract>
672
673L<Class::DBI> for an example of this module in use.
674
675=cut
676
677112µs1;