]> git.decadent.org.uk Git - maypole.git/blobdiff - lib/Maypole/Manual/Inheritance.pod
removed C3 and no longer require it
[maypole.git] / lib / Maypole / Manual / Inheritance.pod
index a20740578a0cde8813474e368439245200592354..950283deb960c2610032c34d5e2112425af1bd98 100644 (file)
@@ -30,14 +30,14 @@ application.
 \r
 =back\r
 \r
-=head1 A standard Maypole application\r
+=head1 Structure of a standard Maypole application\r
 \r
-A minimal Maypole application (such as the Beer database) consists of a \r
-custom driver class (BeerDB.pm), a set of auto-generated model classes, and a \r
-view class: \r
+A minimal Maypole application (such as the Beer database example from the\r
+L<Maypole> synopsis) consists of a custom driver (or controller) class (BeerDB.pm),\r
+a set of auto-generated model classes, and a view class:\r
 \r
 \r
-                  THE DRIVER\r
+           THE DRIVER\r
                                           +------- init() is a factory method,\r
                    1      Maypole         |           it sets up the view\r
    Maypole::Config <----- config();       |              classes\r
@@ -58,14 +58,14 @@ view class:
     |     it sets up the model\r
     |         classes\r
     |\r
-    |                                 THE MODEL\r
+    |                                             THE MODEL\r
     |\r
-    |  Maypole::Model::Base   Class::DBI\r
-    |             +             +\r
-    |             |             |\r
-    +-------> Maypole::Model::CDBI\r
-                      +\r
-                      |\r
+    |  Maypole::Model::Base    Class::DBI\r
+    |             +             +      +\r
+    |             |             |      |\r
+    +-------> Maypole::Model::CDBI   Class::DBI::<db_driver>\r
+                      +                     +\r
+                      |                     |\r
            +------------+--------+-------+---------+\r
            |            |        |       |         |\r
        BeerDB::Pub      |   BeerDB::Beer | BeerDB::Brewery\r
@@ -76,6 +76,11 @@ view class:
           pub();                      BeerDB::Style\r
           beer();                     beers();\r
 \r
+=head2 Ouch, that's a lot of inheritence!\r
+\r
+Yes, that's a lot of inheritence, at some point in the future - probably Maypole 3.x we\r
+will move to Class::C3\r
+\r
 =head2 What about Maypole::Application - loading plugins\r
 \r
 The main job of L<Maypole::Application> is to insert the plugins into the\r
@@ -92,25 +97,31 @@ itself in the hierarchy, but this was unnecessary).
 \r
 =head2 Who builds the model?\r
 \r
-First, remember we are talking about the standard, unmodified Maypole here. \r
-It is possible, and common, to override some or all of this stage and build a \r
-customised model.\r
+First, remember we are talking about the standard, unmodified Maypole here. It\r
+is possible, and common, to override some or all of this stage and build a\r
+customised model. See below - An advanced Maypole application - for one\r
+approach. Also, see L<Maypole's|Maypole> C<setup_model()> method. \r
 \r
 The standard model is built in 3 stages. \r
 \r
-First, C<Maypole::setup> calls C<setup_database> on the Maypole model class, in\r
-this case L<Maypole::Model::CDBI>. C<setup_database> then uses\r
+First, C<Maypole::setup_model> calls C<setup_database> on the Maypole model\r
+class, in this case L<Maypole::Model::CDBI>. C<setup_database> then uses\r
 L<Class::DBI::Loader> to autogenerate individual L<Class::DBI> classes for each\r
 of the tables in the database (C<BeerDB::Beer>, C<BeerDB::Pub> etc).\r
+L<Class::DBI::Loader> identifies the appropriate L<Class::DBI> subclass and\r
+inserts it into each of these table classes' C<@ISA> ( C<<\r
+Class::DBI::<db_driver> >> in the diagrams)..\r
 \r
-Next, C<Maypole::setup> B<unshifts> L<Maypole::Model::CDBI> onto the C<@ISA> \r
+Next, C<Maypole::setup> B<pushes> L<Maypole::Model::CDBI> onto the C<@ISA> \r
 array of each of these classes. \r
 \r
 Finally, the relationships among these tables are set up. Either do this\r
-manually, perhaps with the help of L<Class::DBI::Relationship>, or use\r
-L<Maypole::Plugin::Relationship>. In the latter case, you need to set up the\r
-relationships configuration before calling C<setup()>.\r
-\r
+manually, using the standard L<Class::DBI> syntax for configuring table\r
+relationships, or try L<Class::DBI::Relationship> (which you can use via\r
+L<Maypole::Plugin::Relationship>). If you use the plugin, you need to set up the\r
+relationships configuration before calling C<setup()>. Be aware that some people\r
+like the convenience of L<Class::DBI::Relationship>, others dislike the\r
+abstraction. YMMV. \r
 \r
 =head1 An advanced Maypole application\r
 \r
@@ -177,8 +188,8 @@ C<BeerDB2::Beer>, you would write:
     use base 'OfflineBeer::Beer';\r
     1;\r
     \r
-This package will be loaded automatically during C<setup()>, and\r
-C<BeerDB2::Maypole::Model> is B<unshifted> onto it's C<@ISA>. \r
+From Maypole 2.11, this package will be loaded automatically during C<setup()>,\r
+and C<BeerDB2::Maypole::Model> is B<pushed> onto it's C<@ISA>.\r
 \r
 Configure relationships either in the individual C<OfflineBeer::*> classes, or\r
 else all together in C<OfflineBeer> itself i.e. not in the Maypole model. This \r
@@ -191,15 +202,16 @@ The resulting model looks like this:
                                           |\r
    Maypole::Model::Base                   |\r
            +                              |\r
-           |       +----------------------+-----------------+\r
-           |       |                                        |\r
-           |       |                                        |\r
-     Maypole::Model::CDBI                                   |     OFFLINE\r
-             +                                              |        MODEL\r
-             |                                              |\r
-     BeerDB2::Maypole::Model                           OfflineBeer\r
-       +                                                    +\r
-       |                                                    |\r
+           |       +-----------------+----+-----------------+\r
+           |       |                 |                      |\r
+           |       |                 |                      |\r
+     Maypole::Model::CDBI            |                      |     OFFLINE\r
+             +                       |                      |        MODEL\r
+             |                       |                      |\r
+     BeerDB2::Maypole::Model  Class::DBI::<db_driver>  OfflineBeer\r
+       +                             +                      +\r
+       |                             |                      |\r
+       +-----------------------------+                      |\r
        |                                                    |\r
        +--- BeerDB2::Pub --------+ OfflineBeer::Pub --------+\r
        |                           beers();                 |\r
@@ -223,12 +235,12 @@ The resulting model looks like this:
 \r
 =head3 Features\r
 \r
-Non-Maypole applications using the Offline model are completely isolated from\r
+1. Non-Maypole applications using the Offline model are completely isolated from\r
 the Maypole application, and need not know it exists at all.\r
 \r
-Methods defined in the Maypole table classes, override methods defined in the\r
-Offline table classes, because C<BeerDB2::Maypole::Model> was unshifted onto the\r
-beginning of each Maypole table class's C<@ISA>. Perl's depth first,\r
+2. Methods defined in the Maypole table classes, override methods defined in the\r
+Offline table classes, because C<BeerDB2::Maypole::Model> was pushed onto the\r
+end of each Maypole table class's C<@ISA>. Perl's depth first,\r
 left-to-right method lookup from e.g. C<BeerDB2::Beer> starts in\r
 C<BeerDB2::Beer>, then C<BeerDB2::Maypole::Model>, C<Maypole::Model::CDBI>,\r
 C<Maypole::Model::Base>, and C<Class::DBI>, before moving on to\r
@@ -242,13 +254,14 @@ C<OfflineBeer::CDBI>. Place this B<first> in the C<@ISA> of both
 C<BeerDB2::Maypole::Model> and C<OfflineBeer>. Note that C<OfflineBeer::CDBI>\r
 does not itself need to inherit from L<Class::DBI>.\r
 \r
-Methods defined in the Maypole model base class (C<BeerDB2::Maypole::Model>),\r
+3. Methods defined in the Maypole model base class (C<BeerDB2::Maypole::Model>),\r
 override methods in the individual Offline table classes, and in the Offline\r
 model base class (C<Offline>). \r
 \r
-Relationships defined in the Offline classes are inherited by the Maypole model.\r
+4. Relationships defined in the Offline classes are inherited by the Maypole\r
+model.\r
 \r
-The Maypole model has full access to the underlying Offline model. \r
+5. The Maypole model has full access to the underlying Offline model. \r
 \r
 =head3 Theory \r
 \r
@@ -265,6 +278,20 @@ calls on the underlying model.
 Whatever label you prefer to use, this approach provides for clear separation of\r
 concerns between the underlying model and the web/user interface, and that's\r
 what it's all about.\r
+\r
+=head1 Advanced applications - building the model by hand ** TODO\r
+\r
+- using Maypole::Model::CDBI::Plain or Maypole::FormBuilder::Model::Plain\r
+- setup_model() and load_model_subclass()\r
+- cutting out all those separate paths to CDBI - they're confusing \r
+\r
+\r
+=head1 Method inheritance ** TODO\r
+\r
+More description of Perl's left-to-right, depth-first method lookup, and where\r
+it's particularly important in Maypole.\r
+\r
+\r
           \r
 =head1 AUTHOR\r
 \r