From: John Napiorkowski Date: Wed, 15 Oct 2008 20:49:45 +0000 (+0000) Subject: doc updates X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b3469a4180c2d1b1cb2c220a1cfe3657e723f440;p=gitmo%2FMooseX-Dependent.git doc updates --- diff --git a/specification.pod b/specification.pod index 6269551..d9a0bbc 100644 --- a/specification.pod +++ b/specification.pod @@ -8,7 +8,7 @@ Specification for extra, declaritive hinting to type constrain definitions. =head1 INTRODUCTION -We'd like to be able to add additional 'hints' when declaring our type +We'd like to be able to add additional 'facets' when declaring our type constraints. These hints would form an extention to the core types built into Moose, such as Str, Object, etc. as well as form the foundation for authors of Type Constraint extentions to also add these hints. The idea is these hints @@ -37,6 +37,15 @@ Therefore, it will be important to make sure the hinting system can degrade or cast gracefully, that way hints defined at the application level will work neatly with those defined at a possible database level. +=head1 PROPOSED SYNTAX + +The following is proposed syntax for the faceted types: + + subtype MyType, + is Str, + which hasMinLenth(5), hasMaxLength(20), + where {}; + =head1 USE CASES The following are possible use cases. @@ -52,11 +61,11 @@ To create a string of 10 characters or less. Since this constraint is captured in the code block it is not introspecable. A possible syntax to declare a Str type constraint with a maximum length hint might be: - my $tc = subtype MaxStr10, as Str[MaxLengthInclusive=>10]; + my $tc = subtype MaxStr10, as Str, which hasMaxInclusiveLength(10); -this information might be instrospectable via something like: +this information might be introspectable via something like: - $tc->meta->hints->max_length_inclusive; ## returns 10 + $tc->meta->facets->max_length_inclusive; ## returns 10 =head2 DataTime and coercion possibilities @@ -67,10 +76,12 @@ be hooked into the hint system to allow more finely tuned coercions: use MooseX::Types::DateTime qw(DateTime); subtype USEasternDataTime, - is DateTime[TimeZone=>'US/Eastern']; + is DateTime, + which hasTimeZone('US/Eastern'); coerce USEasternDataTime, - from DateTime[TimeZone=>'Floating']; + from DateTime, + which hasTimeZone('Floating') via {$_->timezone('US/Eastern')}; The created subtype USEasternDataTime would only pass if the DateTime object @@ -79,26 +90,93 @@ information to the canonical type. =head2 Code generation and mapping -Given a type constraint such as: - - subtype MaxStr10, as Str[MaxLengthInclusive=>10]; +Given a type constraint such as: + + subtype ValidName, + as Str, + which hasMaxInclusiveLength(45), isAlpha(), That becomes part of a class definition: package MyApp::Person; ... - has 'short_name' => (isa=>MaxStr10); + has 'name' => (isa=>ValidName, required=>1); A code generator or interpreter could introspect the metadata on the attribute 'short_name' to create a table like: CREATE TABLE Person ( - short_name varchar(10) + short_name varchar(45) + ); + +Please note how the code generator would need to aggregate meta information from +both the attribute options as well as it's type constraint, since in this case +the attribute is required. Here's another, more complicated option. + + package MyApp::Types::StatisticsPeople; + + ## both types are limited to 45 alphabetical characters that define a + ## single word (no whitespace before or after), like "John", but not allow + ## " John", " John ", "john123", etc. + + subtype FirstName, + as Str, + which hasMaxInclusiveLength(45), isAlpha(), isWord(); + + subtype ValidName, + as Str, + which hasMaxInclusiveLength(45), isAlpha(), isWord(); + + package MyApp::Person; + + use Moose; + use MyApp::Types::StatisticsPeople (qw/FirstName LastName/); + + has first_name => (isa=>FirstName, required=>1); + has last_name => (isa=>LastName, required=>1); + +The above might be generated into sql like so (let's assume a database that +has schema support, like Postgresql, + + CREATE TABLE StatisticsPeople.FirstName ( + first_name_id uuid, + value varchar(45), + PRIMARY KEY('first_name_id') + ); + + CREATE TABLE StatisticsPeople.LastName ( + last_name_id uuid, + value varchar(45), + PRIMARY KEY('last_name_id') + ); + + CREATE TABLE PersonFirstName ( + fk_person_id uuid, + fk_first_name_id uuid, + PRIMARY KEY('fk_person_id', 'fk_first_name_id'), + ) + + CREATE TABLE Person ( + person_id uuid, + fk_first_name_id uuid, + fk_last_name_id uuid, + PRIMARY KEY ('person_id') + CONSTRAINT 'person_validname' + FOREIGN KEY ('fk_last_name_id') + REFERENCES 'ValidName' ('valid_name_id'), ); + my $person = model('Person')->create({ + person_first_name => { first_name => {value=>'John'} }, + ... + }); + +Probably an extreme options, but if we have types with all this meta data, why +not have it reflect down to the database model? + [Addional Code examples to follow] -=head1 CORE TYPES AND HINT HEIRARCHY +=head1 CORE TYPES AND FACET HEIRARCHY The following is an outline of the possible hints associated with core Moose type constraints. Hints are assumed to be inherited. @@ -130,12 +208,13 @@ DDUNCAN Int[ Signed UnSigned + Even + Odd ] - SmallInt - BigInt Str[ ASCII* Printable* + isDigits* (That is, a string that is a number like "123") Word (must be a single 'word') MaxLength MinLength @@ -152,6 +231,8 @@ DDUNCAN ArrayRef[`a][ MaxElements MinElements + hasDuplicates + hasOnlyUnique ] HashRef[`a][ HasAllKeys @@ -168,3 +249,7 @@ DDUNCAN Requires Does ] + +** +Might like to have some stuff from the Math packages, like to validate if a +value matches a given function, or is in the domain or range of a function. \ No newline at end of file