1
package Class::Meta::Type;
3
# $Id: Type.pm 2405 2005-12-17 03:41:09Z theory $
7
Class::Meta::Type - Data type validation and accessor building.
11
package MyApp::TypeDef;
14
use Class::Meta::Type;
17
my $type = Class::Meta::Type->add( key => 'io_socket',
18
desc => 'IO::Socket object',
19
name => 'IO::Socket Object' );
23
This class stores the various data types used by C<Class::Meta>. It manages
24
all aspects of data type validation and method creation. New data types can be
25
added to Class::Meta::Type by means of the C<add()> constructor. This is
26
useful for creating custom types for your Class::Meta-built classes.
28
B<Note:>This class manages the most advanced features of C<Class::Meta>.
29
Before deciding to create your own accessor closures as described in L<add()>,
30
you should have a thorough working knowledge of how Class::Meta works, and
31
have studied the L<add()> method carefully. Simple data type definitions such
32
as that shown in the L<SYNOPSIS>, on the other hand, are encouraged.
36
##############################################################################
38
##############################################################################
41
##############################################################################
43
##############################################################################
44
our $VERSION = "0.52";
46
##############################################################################
47
# Private Package Globals #
48
##############################################################################
50
'default' => 'Class::Meta::AccessorBuilder',
51
'affordance' => 'Class::Meta::AccessorBuilder::Affordance',
52
'semi-affordance' => 'Class::Meta::AccessorBuilder::SemiAffordance',
55
# This code ref builds object/reference value checkers.
56
my $class_validation_generator = sub {
57
my ($pkg, $type) = @_;
60
return unless defined $_[0];
61
UNIVERSAL::isa($_[0], $pkg)
62
or $_[2]->class->handle_error("Value '$_[0]' is not a valid "
68
##############################################################################
69
# Data type definition storage.
70
##############################################################################
74
##############################################################################
76
##############################################################################
82
my $type = Class::Meta::Type->new($key);
84
Returns the data type definition for an existing data type. The definition
85
will be looked up by the C<$key> argument. Use C<add()> to specify new types.
86
If no data type exists for a given key, but C<< Class::Meta->for_key >>
87
returns a Class::Meta::Class object for that key, then C<new()> will
88
implicitly call C<add()> to create add a new type corresponding to that
89
class. This makes it easy to use any Class::Meta class as a data type.
91
Other data types can be added by means of the C<add()> constructor, or by
92
simply C<use>ing one or more of the following modules:
96
=item L<Class::Meta::Types::Perl|Class::Meta::Types::Perl>
112
=item L<Class::Meta::Types::String|Class::Meta::Types::String>
120
=item L<Class::Meta::Types::Boolean|Class::Meta::Types::Boolean>
128
=item L<Class::Meta::Types::Numeric|Class::Meta::Types::Numeric>
146
Read the documentation for the individual modules for details on their data
154
|| Class::Meta->handle_error("Type argument required");
155
unless (exists $types{$key}) {
156
# See if there's a Class::Meta class defined for this key.
157
my $cmc = Class::Meta->for_key($key)
158
or Class::Meta->handle_error("Type '$key' does not exist");
160
# Create a new type for this class.
163
name => $cmc->package,
164
check => $cmc->package
167
return bless $types{$key}, $class;
170
##############################################################################
174
my $type = Class::Meta::Type->add( key => 'io_socket',
175
name => 'IO::Socket Object',
176
desc => 'IO::Socket object' );
178
Creates a new data type definition and stores it for future use. Use this
179
constructor to add new data types to meet the needs of your class. The named
180
parameter arguments are:
186
Required. The key with which the data type can be looked up in the future via a
187
call to C<new()>. Note that the key will be used case-insensitively, so "foo",
188
"Foo", and "FOO" are equivalent, and the key must be unique.
192
Required. The name of the data type. This should be formatted for display
193
purposes, and indeed, Class::Meta will often use it in its own exceptions.
197
Optional. Specifies how to validate the value of an attribute of this type.
198
The check parameter can be specified in any of the following ways:
204
As a code reference. When Class::Meta executes this code reference, it will
205
pass in the value to check, the object for which the attribute will be set,
206
and the Class::Meta::Attribute object describing the attribute. If the attribute
207
is a class attribute, then the second argument will not be an object, but a
208
hash reference with two keys:
214
The existing value for the attribute is stored under the attribute name.
218
The name of the package to which the attribute is being assigned.
222
If the new value is not the proper value for your custom data type, the code
223
reference should throw an exception. Here's an example; it's the code
224
reference used by "string" data type, which you can add to Class::Meta::Type
225
simply by using Class::Meta::Types::String:
229
return unless defined $value && ref $value;
231
our @CARP_NOT = qw(Class::Meta::Attribute);
232
Carp::croak("Value '$value' is not a valid string");
235
Here's another example. This code reference might be used to make sure that a
236
new value is always greater than the existing value.
239
my ($new_val, $obj, $attr) = @_;
240
# Just return if the new value is greater than the old value.
241
return if defined $new_val && $new_val > $_[1]->{$_[2]->get_name};
243
our @CARP_NOT = qw(Class::Meta::Attribute);
244
Carp::croak("Value '$new_val' is not greater than '$old_val'");
249
As an array reference. All items in this array reference must be code
250
references that perform checks on a value, as specified above.
254
As a string. In this case, Class::Meta::Type assumes that your data type
255
identifies a particular object type. Thus it will use the string to construct
256
a validation code reference for you. For example, if you wanted to create a
257
data type for IO::Socket objects, pass the string 'IO::Socket' to the check
258
parameter and Class::Meta::Type will use the code reference returned by
259
C<class_validation_generator()> to generate the validation checks. If you'd
260
like to specify an alternative class validation code generator, pass one to
261
the C<class_validation_generator()> class method. Or pass in a code reference
262
or array reference of code reference as just described to use your own
267
Note that if the C<check> parameter is not specified, there will never be any
268
validation of your custom data type. And yes, there may be times when you want
269
this -- The default "scalar" and "boolean" data types, for example, have no
274
Optional. This parameter specifies the accessor builder for attributes of this
275
type. The C<builder> parameter can be any of the following values:
281
The string 'default' uses Class::Meta::Type's default accessor building code,
282
provided by Class::Meta::AccessorBuilder. This is the default value, of
287
The string 'default' uses Class::Meta::Type's affordance accessor building
288
code, provided by Class::Meta::AccessorBuilder::Affordance. Affordance accessors
289
provide two accessors for an attribute, a C<get_*> accessor and a C<set_*>
291
L<Class::Meta::AccessorBuilder::Affordance|Class::Meta::AccessorBuilder::Affordance>
292
for more information.
294
=item "semi-affordance"
296
The string 'default' uses Class::Meta::Type's semi-affordance accessor
297
building code, provided by Class::Meta::AccessorBuilder::SemiAffordance.
298
Semi-affordance accessors differ from affordance accessors in that they do not
299
prepend C<get_> to the accessor. So for an attribute "foo", the accessor would
300
be named C<foo()> and the mutator named C<set_foo()>. See
301
L<Class::Meta::AccessorBuilder::SemiAffordance|Class::Meta::AccessorBuilder::SemiAffordance>
302
for more information.
306
Pass in the name of a package that contains the functions C<build()>,
307
C<build_attr_get()>, and C<build_attr_set()>. These functions will be used to
308
create the necessary accessors for an attribute. See L<Custom Accessor
309
Building|"Custom Accessor Building"> for details on creating your own
320
# Make sure we can process the parameters.
321
Class::Meta->handle_error("Odd number of parameters in "
322
. "call to new() when named "
323
. "parameters were expected")
328
# Check required paremeters.
329
foreach (qw(key name)) {
330
Class::Meta->handle_error("Parameter '$_' is required")
334
# Check the key parameter.
335
$params{key} = lc $params{key};
336
Class::Meta->handle_error("Type '$params{key}' already defined")
337
if exists $types{$params{key}};
339
# Set up the check croak.
341
Class::Meta->handle_error(
342
"Paremter 'check' in call to add() must be a code reference, "
343
. "an array of code references, or a scalar naming an object "
348
# Check the check parameter.
349
if ($params{check}) {
350
my $ref = ref $params{check};
352
# It names the object to be checked. So generate a validator.
354
$class_validation_generator->(@params{qw(check name)});
355
$params{check} = [$params{check}]
356
if ref $params{check} eq 'CODE';
357
} elsif ($ref eq 'CODE') {
358
$params{check} = [$params{check}]
359
} elsif ($ref eq 'ARRAY') {
360
# Make sure that they're all code references.
361
foreach my $chk (@{$params{check}}) {
362
$chk_die->() unless ref $chk eq 'CODE';
370
# Check the builder parameter.
371
$params{builder} ||= $pkg->default_builder;
373
my $builder = $def_builders{$params{builder}} || $params{builder};
374
# Make sure it's loaded.
375
eval "require $builder" or die $@;
377
$params{builder} = UNIVERSAL::can($builder, 'build')
378
|| Class::Meta->handle_error("No such function "
379
. "'${builder}::build()'");
381
$params{attr_get} = UNIVERSAL::can($builder, 'build_attr_get')
382
|| Class::Meta->handle_error("No such function "
383
. "'${builder}::build_attr_get()'");
385
$params{attr_set} = UNIVERSAL::can($builder, 'build_attr_set')
386
|| Class::Meta->handle_error("No such function "
387
. "'${builder}::build_attr_set()'");
389
# Okay, add the new type to the cache and construct it.
390
$types{$params{key}} = \%params;
393
if (my $alias = delete $params{alias}) {
395
$types{$_} = \%params for @$alias;
397
$types{$alias} = \%params;
400
return $pkg->new($params{key});
404
##############################################################################
408
=head2 default_builder
410
my $default_builder = Class::Meta::Type->default_builder;
411
Class::Meta::Type->default_builder($default_builder);
413
Get or set the default builder class attribute. The value can be any one of
414
the values specified for the C<builder> parameter to add(). The value set in
415
this attribute will be used for the C<builder> parameter to to add() when none
416
is explicitly passed. Defaults to "default".
420
my $default_builder = 'default';
421
sub default_builder {
423
return $default_builder unless @_;
424
$default_builder = shift;
428
##############################################################################
430
=head2 class_validation_generator
432
my $gen = Class::Meta::Type->class_validation_generator;
433
Class::Meta::Type->class_validation_generator( sub {
434
my ($pkg, $name) = @_;
436
die "'$pkg' is not a valid $name"
437
unless UNIVERSAL::isa($pkg, $name);
441
Gets or sets a code reference that will be used to generate the validation
442
checks for class data types. That is to say, it will be used when a string is
443
passed to the C<checks> parameter to <add()> to generate the validation
444
checking code for data types that are objects. By default, it will generate a
445
validation checker like this:
449
return if UNIVERSAL::isa($value, 'IO::Socket')
451
our @CARP_NOT = qw(Class::Meta::Attribute);
452
Carp::croak("Value '$value' is not a IO::Socket object");
455
But if you'd like to specify an alternate validation check generator--perhaps
456
you'd like to throw exception objects rather than use Carp--just pass a code
457
reference to this class method. The code reference should expect two
458
arguments: the data type value to be validated, and the string passed via the
459
C<checks> parameter to C<add()>. It should return a code reference or array of
460
code references that validate the value. For example, you might want to do
461
something like this to throw exception objects:
463
use Exception::Class('MyException');
465
Class::Meta::Type->class_validation_generator( sub {
466
my ($pkg, $type) = @_;
468
my ($value, $object, $attr) = @_;
469
MyException->throw("Value '$value' is not a valid $type")
470
unless UNIVERSAL::isa($value, $pkg);
474
But if the default object data type validator is good enough for you, don't
479
sub class_validation_generator {
481
return $class_validation_generator unless @_;
482
$class_validation_generator = shift;
485
##############################################################################
487
##############################################################################
491
=head2 Instance Methods
495
my $key = $type->key;
497
Returns the key name for the type.
501
my $name = $type->name;
503
Returns the type name.
507
my $checks = $type->check;
508
my @checks = $type->check;
510
Returns an array reference or list of the data type validation code references
515
sub key { $_[0]->{key} }
516
sub name { $_[0]->{name} }
518
return unless $_[0]->{check};
519
wantarray ? @{$_[0]->{check}} : $_[0]->{check}
522
##############################################################################
526
This is a protected method, designed to be called only by the
527
Class::Meta::Attribute class or a subclass of Class::Meta::Attribute. It
528
creates accessors for the class that the Class::Meta::Attribute object is a
529
part of by calling out to the C<build()> method of the accessor builder class.
531
Although you should never call this method directly, subclasses of
532
Class::Meta::Type may need to override its behavior.
537
# Check to make sure that only Class::Meta or a subclass is building
538
# attribute accessors.
540
Class::Meta->handle_error("Package '$caller' cannot call "
541
. __PACKAGE__ . "->build")
542
unless UNIVERSAL::isa($caller, 'Class::Meta::Attribute');
545
my $code = $self->{builder};
546
$code->(@_, $self->check);
550
##############################################################################
554
This is a protected method, designed to be called only by the
555
Class::Meta::Attribute class or a subclass of Class::Meta::Attribute. It
556
returns a reference to the attribute set accessor (mutator) created by the
557
call to C<build()>, and usable as an indirect attribute accessor by the
558
Class::Meta::Attribute C<set()> method.
560
Although you should never call this method directly, subclasses of
561
Class::Meta::Type may need to override its behavior.
567
my $code = $self->{attr_set};
571
##############################################################################
575
This is a protected method, designed to be called only by the
576
Class::Meta::Attribute class or a subclass of Class::Meta::Attribute. It
577
returns a reference to the attribute get accessor created by the call to
578
C<build()>, and usable as an indirect attribute accessor by the
579
Class::Meta::Attribute C<get()> method.
581
Although you should never call this method directly, subclasses of
582
Class::Meta::Type may need to override its behavior.
588
my $code = $self->{attr_get};
595
=head1 CUSTOM DATA TYPES
597
Creating custom data types can be as simple as calling C<add()> and passing in
598
the name of a class for the C<check> parameter. This is especially useful when
599
you just need to create attributes that contain objects of a particular type,
600
and you're happy with the accessors that Class::Meta will create for you. For
601
example, if you needed a data type for a DateTime object, you can set it
602
up--complete with validation of the data type, like this:
604
my $type = Class::Meta::Type->add( key => 'datetime',
606
desc => 'DateTime object',
607
name => 'DateTime Object' );
609
From then on, you can create attributes of the type "datetime" without any
610
further work. If you wanted to use affordance accessors, you'd simply
611
add the requisite C<builder> attribute:
613
my $type = Class::Meta::Type->add( key => 'datetime',
615
builder => 'affordance',
616
desc => 'DateTime object',
617
name => 'DateTime Object' );
619
The same goes for using semi-affordance accessors.
621
Other than that, adding other data types is really a matter of the judicious
622
use of the C<check> parameter. Ultimately, all attributes are scalar
623
values. Whether they adhere to a particular data type depends entirely on the
624
validation code references passed via C<check>. For example, if you wanted to
625
create a "range" attribute with only the allowed values 1-5, you could do it
628
my $range_chk = sub {
630
die "Value is not a number" unless $value =~ /^[1..5]$/;
633
my $type = Class::Meta::Type->add( key => 'range',
635
desc => 'Pick a number between 1 and 5',
636
name => 'Range (1-5)' );
638
Of course, the above value validator will throw an exception with the
639
line number from which C<die> is called. Even better is to use L<Carp|Carp>
640
to throw an error with the file and line number of the client code:
642
my $range_chk = sub {
644
return if $value =~ /^[1..5]$/;
646
our @CARP_NOT = qw(Class::Meta::Attribute);
647
Carp::croak("Value is not a number");
650
The C<our @CARP_NOT> line prevents the context from being thrown from within
651
Class::Meta::Attribute, which is useful if you make use of that class'
654
=head2 Custom Accessor Building
656
Class::Meta also allows you to craft your own accessors. Perhaps you'd prefer
657
to use a StudlyCaps affordance accessor standard. In that case, you'll need to
658
create your own module that builds accessors. I recommend that you study
659
L<Class::Meta::AccessorBuilder|Class::Meta::AccessorBuilder> and
660
LClass::Meta::AccessorBuilder::Affordance|Class::Meta::AccessorBuilder::Affordance>
661
before taking on creating your own.
663
Custom accessor building modules must have three functions.
667
The C<build()> function creates and installs the actual accessor methods in a
668
class. It should expect the following arguments:
671
my ($class, $attribute, $create, @checks) = @_;
681
The name of the class into which the accessors are to be installed.
685
A Class::Meta::Attribute object representing the attribute for which accessors
686
are to be created. Use it to determine what types of accessors to create
687
(read-only, write-only, or read/write, class or object), and to add checks for
688
requiredness and accessibility (if the attribute is private or protected).
692
The value of the C<create> paramter passed to Class::Meta::Attribute when the
693
attribute object was created. Use this argument to determine what type of
694
accessor(s) to create. See L<Class::Meta::Attribute|Class::Meta::Attribute>
695
for the possible values for this argument.
699
A list of one or more data type validation code references. Use these in any
700
accessors that set attribute values to check that the new value has a valid
705
See L<Class::Meta::AccessorBuilder|Class::Meta::AccessorBuilder> for example
706
attribute creation functions.
708
=head3 build_attr_get and build_attr_set
710
The C<build_attr_get()> and C<build_attr_set()> functions take a single
711
argument, a Class::Meta::Attribute object, and return code references that
712
either represent the corresponding methods, or that call the appropriate
713
accessor methods to get and set an attribute, respectively. The code
714
references will be used by Class::Meta::Attribute's C<get()> and
715
C<set()> methods to get and set attribute values. Again, see
716
L<Class::Meta::AccessorBuilder|Class::Meta::AccessorBuilder> for examples
717
before creating your own.
721
Please send bug reports to <bug-class-meta@rt.cpan.org> or report them via the
722
CPAN Request Tracker at L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Class-Meta>.
726
David Wheeler <david@kineticode.com>
730
Other classes of interest within the Class::Meta distribution include:
734
=item L<Class::Meta|Class::Meta>
736
This class contains most of the documentation you need to get started with
739
=item L<Class::Meta::Attribute|Class::Meta::Attribute>
741
This class manages Class::Meta class attributes, all of which are based on
746
These modules provide some data types to get you started:
750
=item L<Class::Meta::Types::Perl|Class::Meta::Types::Perl>
752
=item L<Class::Meta::Types::String|Class::Meta::Types::String>
754
=item L<Class::Meta::Types::Boolean|Class::Meta::Types::Boolean>
756
=item L<Class::Meta::Types::Numeric|Class::Meta::Types::Numeric>
760
The modules that Class::Meta comes with for creating accessors are:
764
=item L<Class::Meta::AccessorBuilder|Class::Meta::AccessorBuilder>
766
Standard Perl-style accessors.
768
=item L<Class::Meta::AccessorBuilder::Affordance|Class::Meta::AccessorBuilder::Affordance>
770
Affordance accessors--that is, explicit and independent get and set accessors.
772
=item L<Class::Meta::AccessorBuilder::SemiAffordance|Class::Meta::AccessorBuilder::SemiAffordance>
774
Semi-ffordance accessors--that is, independent get and set accessors with an
775
explicit set accessor.
779
=head1 COPYRIGHT AND LICENSE
781
Copyright (c) 2002-2005, David Wheeler. All Rights Reserved.
783
This module is free software; you can redistribute it and/or modify it under
784
the same terms as Perl itself.