[svn:p5ee] r6835 - in p5ee/trunk/App-Context/lib: . App App/adminguide App/installguide

[email protected]
Newsgroups perl.cvs.p5ee
Message-ID <[email protected]>
Author: spadkins
Date: Sun Sep  3 18:42:26 2006
New Revision: 6835

Added:
   p5ee/trunk/App-Context/lib/App/adminguide/
   p5ee/trunk/App-Context/lib/App/adminguide/cvs.pod
   p5ee/trunk/App-Context/lib/App/datetime.pod
   p5ee/trunk/App-Context/lib/App/devguide.pod
   p5ee/trunk/App-Context/lib/App/exceptions.pod
   p5ee/trunk/App-Context/lib/App/faq.pod
   p5ee/trunk/App-Context/lib/App/installguide/
   p5ee/trunk/App-Context/lib/App/installguide.pod
   p5ee/trunk/App-Context/lib/App/installguide/hosted.pod
   p5ee/trunk/App-Context/lib/App/installguide/win32.pod
   p5ee/trunk/App-Context/lib/App/perlstyle.pod
Modified:
   p5ee/trunk/App-Context/lib/App.pm
   p5ee/trunk/App-Context/lib/App/Context.pm

Log:
starting to get the documentation in shape

Modified: p5ee/trunk/App-Context/lib/App.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App.pm	(original)
+++ p5ee/trunk/App-Context/lib/App.pm	Sun Sep  3 18:42:26 2006
@@ -30,10 +30,15 @@
     $object  = App->new($class, $method);
     $object  = App->new($class, $method, @args);
 
+=head1 DOCUMENT STATUS
+
+This documentation is out of date and needs review and revision.
+
+Please start with the L<App::quickstart> document.
+
 =head1 DESCRIPTION
 
-The App module is the module from which core services are
-called.
+The App module is the module from which core services are called.
 
 =cut
 

Modified: p5ee/trunk/App-Context/lib/App/Context.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/Context.pm	(original)
+++ p5ee/trunk/App-Context/lib/App/Context.pm	Sun Sep  3 18:42:26 2006
@@ -43,6 +43,12 @@
 # CONSTANTS
 #############################################################################
 
+=head1 DOCUMENT STATUS
+
+This documentation is out of date and needs review and revision.
+
+Please start with the L<App::quickstart> document.
+
 =head1 DESCRIPTION
 
 A Context class models the environment (aka "context")

Added: p5ee/trunk/App-Context/lib/App/adminguide/cvs.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/adminguide/cvs.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,238 @@
+#!perl -w
+# run this document through perl to check its syntax
+use Pod::Checker;
+podchecker(\*DATA);
+__END__
+
+=head1 NAME
+
+App::adminguide::cvs - Administration Guide for CVS
+
+=head1 DESCRIPTION
+
+The following is a list of installation stories for installing CVS correctly.
+
+=head1 REFERENCES
+
+  CVS Home Page
+    - https://www.cvshome.org/
+  Configuration of xinetd
+    - http://www.sugoi.org/bits/index.php?bit_id=32
+   
+=head1 CVS INSTALLATION : 2004-08-06 : REDHAT LINUX
+
+I wanted to move a CVS installation from a server we were
+decommissioning to a new server, and I wanted to get two
+things right this time (which I had neglected the first
+time around).
+
+  * cvspserver not running as root
+  * cvs using a CVS passwd file, not /etc/passwd
+
+Furthermore, the old installation was on Solaris 2.7 which
+used an inetd configuration.  My new installation would
+by on RedHat Linux 9 (2.4.21 kernel).
+
+=head2 CVS software installation
+
+I checked the version of CVS installed on the system.
+
+  cvs --version
+  rpm -q cvs
+
+and found I had version 1.11.2 installed.
+I checked the CVS home page, and it alerted me to a
+vulnerability in CVS if this were exposed to the 
+internet (which I had some sense I might do).
+
+  http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0396
+
+So I had to install 1.11.16 or greater (1.11 series) or 1.12.8
+or greater (1.12 series).  The latest releases are 1.12.9 and
+1.11.17.  I decided to go with an rpm installation rather than
+a source-based installation.  I decided to go with the 1.11
+series, which cvshome.org says is the "stable" version rather
+than the 1.12 version which cvshome.org says is an incremental
+feature version.
+
+  su -
+  cd /root
+  mkdir rpm
+  cd rpm
+  wget ftp://rpmfind.net/linux/fedora/core/updates/2/i386/cvs-1.11.17-2.i386.rpm
+  rpm --upgrade cvs-1.11.17-2.i386.rpm
+
+But then "cvs --version" caused the following error.
+
+  cvs: relocation error: cvs: undefined symbol: GSS_C_NT_HOSTBASED_SERVICE
+
+So I decided to go with the RPM from cvshome.org rather than from Fedora.
+
+  wget https://ccvs.cvshome.org/files/documents/19/360/cvs-1.11.17-1.i386.rpm
+  rpm --upgrade cvs-1.11.17-1.i386.rpm
+
+This gave me the following error.
+
+  package cvs-1.11.17-2 (which is newer than cvs-1.11.17-1) is already installed
+
+So I did
+
+  rpm --upgrade --force cvs-1.11.17-1.i386.rpm
+
+and that did the trick, as verified by
+
+  rpm -q cvs
+  cvs --version
+
+If that had not worked, I would have compiled my own version from
+sources, but I would have to be sure to use ./configure --prefix=/usr
+so that the binaries would overwrite the installed binaries rather
+than creating another version in /usr/local.
+
+Somewhere else I read that I need to set the setgid bit on the
+cvs binary.
+
+  chmod 2755 /usr/bin/cvs
+
+=head2 Users and Groups
+
+We use NIS, so I verified that we have both the cvs user and group
+defined.
+
+  ypcat passwd | grep cvs
+  ypcat group | grep cvs
+
+Otherwise, I would have verified that in the /etc/passwd and 
+/etc/group files and created them if necessary.
+
+=head2 CVSROOT
+
+I chose /usr/mycompany/cvs (where "mycompany" is replaced with a
+name for our company) for all CVS files (i.e. CVSROOT).
+
+  cd /usr/mycompany
+  mkdir cvs
+  chown cvs cvs
+  chgrp cvs cvs
+  chmod 775 cvs
+  chmod g+s cvs
+
+We use Bash and Korn shell, so I added the following lines to
+"/etc/profile" so that the CVSROOT variable is available to all
+users.
+
+  CVSROOT=/usr/mycompany/cvs
+  export CVSROOT
+
+Then I ran the same commands in my current shell to set CVSROOT for
+the current session.
+
+=head2 Initializing the CVS Repository
+
+I initialized the CVS Repository (/usr/mycompany/cvs).
+
+  su - cvs
+  cvs init
+
+Then I created the CVS password file.
+
+  cd ~
+  mkdir src
+  cd src
+  cvs co CVSROOT
+  cd CVSROOT
+  touch passwd
+  cvs add passwd
+  cvs update
+  cvs commit -m "new" passwd
+
+  vi checkoutlist
+  # add "passwd" as the last line
+  cvs commit -m "added passwd to list of CVSROOT files" checkoutlist
+
+Then exit as the "cvs" user.
+
+  exit
+
+=head2 Installing cvspasswd and adding users
+
+I got it from here.
+
+  http://www.sugoi.org/bits/download/cvspasswd
+
+But I put it in a distribution on CPAN called App-admin.
+So you can install it this way.
+
+  perl -MCPAN -e "install App-admin"
+
+In any case, make sure it is in your path (i.e. /usr/local/bin).
+Then add users.
+
+  cvspasswd joe    joespw7
+  cvspasswd mike   m1k31sgr3a7
+  cvspasswd nellie whoa_
+
+=head2 Configure xinetd
+
+On Solaris, I just needed to add a line to /etc/inetd.conf which
+looked like this. (This configures "inetd", the internetworking daemon.)
+
+  cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/usr/mycompany/cvs pserver
+
+However, on Linux I have to configure xinetd (an enhanced version of
+"inetd").
+
+  cd /etc/xinetd.d
+  vi cvs
+
+I put the following in the file, with my server's actual
+IP address instead of "10.10.10.10".
+
+  service cvspserver
+  {
+      disable         = no
+      socket_type     = stream
+      wait            = no
+      user            = cvs
+      group           = cvs
+      log_type        = FILE /var/log/cvspserver
+      protocol        = tcp
+      env             = '$HOME=/usr/mycompany/cvs'
+      bind            = 10.10.10.10
+      log_on_failure += USERID
+      port            = 2401
+      server          = /usr/bin/cvs
+      server_args     = -f --allow-root=/usr/mycompany/cvs pserver
+  }
+
+Then I restart xinetd.
+
+  pkill -HUP xinetd
+
+=head2 Verification
+
+Then I went to another server on the network.
+
+  cd ~
+  mkdir src
+  cd src
+  cvs -d :pserver:mike@cvshost:/usr/mycompany/cvs login
+  cvs -d :pserver:mike@cvshost:/usr/mycompany/cvs co CVSROOT
+  # it worked great, so I can remove it ...
+  rm -rf CVSROOT
+
+=head2 Moving the CVS data
+
+I now had to move the data from my old CVS server.
+
+  ssh oldcvshost
+  su -
+  cd /usr/mycompany/cvs
+  find project1 project2 project3 -print | cpio -ocv | gzip > cvs.cpio.gz
+  scp cvs.cpio.gz mike@cvshost:.
+  ssh mike@cvshost
+  su -
+  cd /usr/mycompany/cvs
+  mv ~mike/cvs.cpio.gz .
+  gunzip < cvs.cpio.gz | cpio -idcuvm
+

Added: p5ee/trunk/App-Context/lib/App/datetime.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/datetime.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,267 @@
+#!perl -w
+# run this document through perl to check its syntax
+use Pod::Checker;
+podchecker(\*DATA);
+__END__
+
+=head1 NAME
+
+App::datetime - Date and Time Considerations
+
+=head1 INTRODUCTION
+
+Most Enterprise development includes processing of dates and times.
+There are many date and time modules on CPAN, and choosing the right
+one can be confusing.
+There are no special perl data types for dates and times,
+so some direction is needed.
+
+The short answer is that we recommend the following
+for most common date and time operations.
+
+ Class::Date
+ Class::Date::Rel
+
+However, other modules are appropriate in certain circumstances.
+So for the longer answer, read on.
+
+=head1 PERL 5 LANGUAGE SUPPORT
+
+The native Perl 5 datetime type is an integer.
+It is not different from other integers in any way other than
+how it is used.
+It represents the number of non-leap seconds since 
+January 1, 1970 UTC (the "Epoch" at GMT).  The following internal
+Perl function gets the current time.
+
+ $current_time = time;
+ $current_time = time();
+
+Other Perl functions that return this "datetime" integer are
+
+ ($dev, $ino, $mode, $nlink, $uid, $gid, $redev, $size,
+  $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
+ ($dev, $ino, $mode, $nlink, $uid, $gid, $redev, $size,
+  $atime, $mtime, $ctime, $blksize, $blocks) = lstat($filename);
+
+where $atime, $mtime, and $ctime are the same kind of integers,
+representing the access time, modification time, and change time
+of a file.
+
+These $time values may be converted to human-readable
+form using the following internal perl functions.
+(See the "perlfunc" man page for more information.)
+
+ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($time);
+ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
+
+Furthermore, the current time zone needs to be accessed through
+the environment variable, "TZ".
+
+ $timezone = $ENV{TZ};
+
+This leaves the Perl developer with lots of work to do in order to
+process dates.
+
+=over
+
+=item * Formatting dates for output
+
+=item * Parsing dates on input
+
+=item * Comparing dates
+
+=item * Date math (addition, subtraction)
+
+=item * Other calendar-specific functions (i.e. holidays, days of week, etc)
+
+=back
+
+Numerous modules have been posted to CPAN allowing the Perl developer
+to accomplish these tasks.
+However, they have pros and cons related to the
+following features.
+
+=over
+
+=item * Internationalization
+
+=item * Speed
+
+=item * Portability
+
+=item * Ranges of Dates Supported
+
+=item * Compliance with Perl Styleguide (function naming)
+
+=back
+
+=head1 FUNCTIONAL SOLUTIONS
+
+Modules exist to allow you to process integers like those
+returned by the time() function.  They do not create "date" objects
+with methods.  They simply provide functions that allow you do the
+required tasks. 
+
+=head2 Date::Parse, Date::Format
+
+ http://search.cpan.org/search?module=Date::Parse
+ http://search.cpan.org/search?module=Date::Format
+
+
+Very simple, clean functions for parsing text dates and formatting
+them for output in a variety of ways.  The fact that these modules
+work with integers implies that you can do date comparisons and
+some degree of date math simply ($tomorrow = $today + 24*60*60;).
+(Beware of date math across days that change to or from daylight
+saving time.)
+
+ * Parses many different formats of dates
+ * Flexible formatting using POSIX strftime() format specifiers.
+ * Limited internationalization support.
+ * Limited date math support.
+ * Unknown support for dates outside [1970-2038]
+
+=head2 Date::Calc
+
+ http://search.cpan.org/search?module=Date::Calc
+
+Powerful, fast manipulation of dates.
+
+ * No explicit support for parsing or formatting dates.
+ * Non-perlstyle function names (internal caps, as in Add_Delta_YMD())
+ * Powerful, fast support for date math
+ * Support for all A.D. dates [1-9999]
+
+=head2 Date::Manip
+
+ http://search.cpan.org/search?module=Date::Manip
+
+The most powerful and slowest (all perl, large)
+of date manipulation packages.
+Includes many obscure calendar-related functions.
+
+ * Powerful parsing many different formats of dates
+ * No explicit support for or formatting dates.
+ * Non-perlstyle function names (internal caps, as in ParseDate())
+ * Powerful support for date math (but slower than Date::Calc)
+ * Support for all A.D. dates [1-9999]
+ * Function support for holidays, business days, etc.
+
+=head2 HTTP::Date
+
+ http://search.cpan.org/search?module=HTTP::Date
+
+This module is part of the larger libwww-perl bundle.
+It seems to parse a wider variety of dates than Date::Parse,
+but it is focused on those date formats which occur in HTTP headers.
+It only formats dates in the format preferred by HTTP headers.
+
+=head2 Time::HiRes
+
+ http://search.cpan.org/search?module=Time::HiRes
+
+Completely separate from the modules above, which deal with dates,
+there is sometimes a need to deal with times at the sub-second
+level.  Time::HiRes works in seconds and milliseconds.
+It is particularly useful in timing sections of code.
+
+=head1 OBJECT-ORIENTED SOLUTIONS
+
+An alternative to the functional solutions described above is an
+object-oriented solution that involves creating and manipulating
+true "datetime" objects.
+
+=head2 DateTime
+
+ http://datetime.perl.org/
+ http://datetime.perl.org/modules.html
+ http://search.cpan.org/~drolsky/DateTime/
+ http://search.cpan.org/~drolsky/DateTime/lib/DateTime.pm
+
+The latest significant entrant (and quite promising) in the perl
+date/time area is Datetime.pm.  It attempts to be the definitive
+date/time module for perl, building on the work of Time::Piece
+and Class::Date. 
+
+Furthermore, the DateTime module is not alone.  Rather, it is
+part of a project where many date/time developers collaborate
+for an entire framework of date/time modules.
+
+ * OO interface
+ * Parsing of dates provided by DateTime::Format::* modules
+ * Flexible formatting using POSIX strftime() format specifiers.
+   (formatting done automatically during object stringification)
+ * Limited internationalization support.
+ * Good date math support.
+ * Unknown support for dates outside [1970-2038]
+ * Moderate support on Win32 platform.
+
+=head2 Time::Piece [Time::Object, Time::Seconds]
+
+ http://search.cpan.org/search?module=Time::Object
+
+On the perl5-porters mailing
+Larry Wall described some thoughts on how dates and times might become part
+of the Perl language and sketched out an object-oriented interface.
+
+ http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-01/msg00241.html
+
+This interface was implemented in the Time::Piece package.
+
+ * OO interface
+ * No explicit support for parsing dates.
+ * Flexible formatting using POSIX strftime() format specifiers.
+ * Limited internationalization support.
+ * Limited date math support.
+ * Unknown support for dates outside [1970-2038]
+ * Unsupported on Win32 platform.
+
+=head2 Class::Date, Class::Date::Rel
+
+ http://search.cpan.org/search?module=Class::Date
+
+This class started with Time::Object and was enhanced.
+
+ * Some native support for parsing dates.
+ * Uses Date::Parse internally for extended date parsing
+ * Better date math support.
+ * Supported on Win32 platform.
+
+=head2 Date::Simple
+
+ http://search.cpan.org/search?module=Date::Simple
+
+This is a simple, object-oriented class that deals with
+dates only (not times at all).
+
+=head2 Date::Calc::Object
+
+ http://search.cpan.org/search?module=Date::Calc::Object
+
+Date::Calc has an object-oriented interface.
+
+=head1 FURTHER RESEARCH
+
+For further research on Date and Time modules in Perl, you can
+subscribe to the [email protected] mailing list.
+
+ http://lists.perl.org/showlist.cgi?name=datetime
+
+You can read up on future directions
+for Perl and date/time support here.
+
+ http://nntp.perl.org/group/perl.perl6.language.datetime
+
+You can also start up the CPAN shell and look for other
+Date and Time modules.
+
+ perl -MCPAN -e shell
+ i /Date/
+ i /Time/
+
+Be warned. You may likely be overwhelmed. (That's why this
+document was written.)
+
+=cut
+

Added: p5ee/trunk/App-Context/lib/App/devguide.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/devguide.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,463 @@
+#!perl -w
+# run this document through perl to check its syntax
+use Pod::Checker;
+podchecker(\*DATA);
+__END__
+
+=head1 NAME
+
+App::devguide - App Developer's Guide
+
+=head1 INTRODUCTION
+
+This is the Developer's Guide to the
+App (Perl 5 Enterprise Environment).
+You can find out more background to the project on the web.
+
+  http://www.officevision.com/pub/p5ee
+  http://p5ee.perl.org
+
+=head1 App DESIGN PHILOSOPHY
+
+When the App project was begun, there were already
+
+ * many outstanding Perl packages on CPAN
+ * an excellent systems architecture for Perl webapps (mod_perl)
+ * several excellent web application development frameworks
+
+So why was App needed?
+
+For a variety of reasons, there was never sufficient unity of
+purpose or direction within the Perl community to provide
+a coherent blueprint of what Enterprise Programming in Perl is
+or how to do it.
+
+ * What are the pieces?
+ * What pieces are default? standard? mandatory? optional?
+ * How do they fit together?
+ * How can I override or customize them?
+ * What techniques do I need to use to assemble them effectively?
+
+After "Enterprise Systems" were defined (see website), the field
+of existing frameworks, solutions, and components was surveyed.
+The goal was to examine everything that people were already doing,
+divide it into pieces that seemed interchangeable, and come up
+with a unified blueprint.  Pieces that people often like to do
+differently (template systems, persistence frameworks, configuration
+files) were allowed to vary, while their essential contribution
+to the working system was standardized in the framework.
+
+It should be noted that most of the work on what people might
+term "Enterprise Systems" in Perl was actually focused on
+"Web Systems" in Perl with a relational database.
+
+The goal of the App design is to unify the Perl community
+on a framework for cooperation, while providing flexibility in
+the areas that might otherwise divide the community.
+
+Essentially, everything in App is overridable and customizable,
+but good defaults are provided for everything as well.
+
+On the practical side, App was also designed to allow for gradual
+adoption and incorporation into existing projects.
+
+=head1 App Execution Flow: CGI
+
+The first step to understanding the flow of execution through
+the App framework is to understand the flow in the CGI
+Context.
+
+This is one of the most challenging contexts
+to develop for because of the stateless nature of HTTP,
+the need to initialize all resources before accessing them,
+and the need to properly shut down all resources after using
+them or in case of user abort.
+
+=head2 cgi-bin/app and the Initialization Config File
+
+All usage of App from the web can be driven through the CGI program,
+"cgi-bin/app".  (Actually, depending on the settings in the Initialization
+Config File, the "app" program might not be a CGI program at all.)
+The app program should be installed at a location which is executable
+as a CGI program such as the following.
+
+  http://www.officevision.com/cgi-bin/pub/p5ee/app
+
+The "app" progam runs with the "-wT" switches turned on for maximum
+safety, security, and enforcement of programming rigor.
+
+Then a BEGIN block is executed to read the Initialization Config File
+to get low level config settings and perhaps modify the @INC variable.
+Modification of the @INC variable in the BEGIN block through configuration
+is critical so that you can have multiple versions of modules installed
+(at various stages of development through testing, production, and support).
+and access the correct ones.
+
+The Initialization Config File (.conf) is located in the following way.
+First, the PATH_INFO is checked and a corresponding .conf file is opened.
+Thus, the following URL
+
+  http://www.officevision.com/cgi-bin/pub/p5ee/app/ecommerce/shop
+
+would open "ecommerce_shop.conf" in the directory of the "app" program. 
+
+If it is not found, "$0.conf" is opened.  That would be "app.conf"
+in this case.  However, you can see that this allows for the "app"
+program to be renamed, and (according to its configuration) it will
+behave like a completely different application.
+
+If it is still not found, "app.conf" is opened.
+If this is not found, no Initialization Config information will be
+used and all defaults will be used.
+
+Whichever .conf file was first opened, it is read for simple configuration
+variables of the form "variable = value".  Anything following a "#" is considered
+a comment.  Leading and trailing spaces are removed, and blank lines are
+ignored.  Spaces may precede or follow the "=" sign without affecting the
+"variable" or the "value".  The "variable" must be a sequence of alphabetic characters
+and ".", "_", or "-" (i.e. matches /[a-zA-Z_.-]+/).  The value may be
+any string of characters (including none), but leading and trailing spaces
+are stripped.  The variable/value pairs are saved in a global hash in %main::conf.
+
+If the "perlinc" variable is set, it is understood to be a comma-separated
+list of directories to search for Perl modules.  This list is placed
+at the beginning of the special Perl @INC variable.
+
+Some sample lines in the .conf file are:
+
+  perlinc = /usr/ov/acoc/dev/src/Appx-Blue, /usr/ov/acoc/dev/lib/perl5/5.6.0
+  debugmode = record
+  showsession = 1
+  gzip = 1
+  configFile = app.pl
+
+The meanings of these variables are:
+
+  perlinc      - directories to search for perl modules
+  debugmode    - (off|record|replay) useful for recording a failed CGI request and replaying it for debugging
+  debug        - (0|1,App::Context::CGI|6,App::Repository::DBI.select_rows)
+  showsession  - (0|1) show the contents of the session in an HTML comment
+  gzip         - (0|1) allows compression of HTML output if the client browser supports it
+
+Additional variables may be provided.  However, suitable defaults
+are usually detected if they are not supplied.
+
+  contextClass - (i.e. App::Context::CGI) class for the context
+  configClass  - (i.e. App::Config::File) class for the config
+  configFile   - (i.e. "config.pl") name of the main configuration file
+  configSerializerClass - (i.e. App::Serializer::Dumper) class for config deserialization
+  sessionClass - (i.e. App::Session::HTMLHidden) class for the session
+  defaultWname - widget name to be the first current_widget to be displayed
+  scriptUrlDir - URL of App script directory (i.e. "/cgi-bin")
+  scriptDir    - Directory corresponding to the scriptUrlDir
+  htmlUrlDir   - URL of App docs directory
+  htmlDir      - Directory corresponding to the htmlUrlDir
+
+After the Initialization Config File is read into %main::conf, the
+command line arguments are scanned for options of the form "-variable" or
+"-variable=value".  (Options may also start with double-dashes, "--".)
+Such options are removed from the command line, and the variable/value
+pair is added to the %main::conf hash, thus overriding any values from
+the Initialization Config File.  The CGI environment never passes options
+to the program in this way (with a preceding dash), so this is mainly
+useful for debugging at the command line
+(i.e. "app -debugmode=replay -debug=1 -gzip=0").
+
+=head2 use App
+
+Next, the App module is included, which does the following:
+
+  * disable "Use of uninitialized value" warnings
+  * use Exception::Class;   # enable Exception inheritance
+  * use App::Exceptions;  # define App exceptions
+
+The base class of all App exceptions is "App::Exception".
+Derived from this base exception, each component service of App
+has its own base class as follows.
+
+  App::Exception::Context
+  App::Exception::Config
+  App::Exception::Serializer
+  App::Exception::Repository
+  App::Exception::Security
+  App::Exception::Session
+  App::Exception::Widget
+  App::Exception::TemplateEngine
+  App::Exception::Procedure
+  App::Exception::Messaging
+  App::Exception::LogChannel
+
+=head2 cgi-bin/app and bootstrapping the environment
+
+The "app" program then executes the following line.
+
+  my $context = App->context(\%main::conf);
+
+This instantiates a $context object, passing the
+global %main::conf hash as an argument.
+
+Note that in other Context implementations other than
+CGI, the $context may survive to serve more than a single
+request or to dispatch many events coming from the network
+or from a user.  In that case, the
+App->context() method may return an
+already-instantiated $context object.  The $context
+is a singleton per process.
+
+=head2 App->context()
+
+If the "contextClass" variable is in the argument hash, it is used.
+Otherwise, if the "app" program is running in the CGI context
+(HTTP_USER_AGENT environment variable is set) or at the
+command line, the App::Context::CGI class
+will be assumed.
+
+The code for the selected class is loaded and a $context
+of the appropriate class is instantiated.
+For the CGI context, the App::Context::CGI->new()
+method is called, and the arguments of the context() method
+call (%main::conf, in this case) are passed on to it.
+
+=head2 App::Context::CGI->new()
+
+The constructor (new()) for App::Context::CGI is actually provided
+by its parent class, App::Context.
+
+If the "configClass" was not specified in the arguments
+(%main::conf, in this case), App::Config::File is assumed.
+It is instantiated, once again passing on the hash of initialization args,
+and the result is stored in $self->{config};
+
+Then the App::Context::CGI->init() method is called to
+complete the $context constructor.  A CGI object is created
+and added to the %args to be passed on to Session instantiation.
+
+If the "sessionClass" was not specified in the arguments,
+App::Session::HTMLHidden is assumed.
+It is instantiated, once again passing on the hash of initialization args,
+and the result is stored in $self->{session};
+
+=head2 App::Config::File->new()
+
+The constructor (new()) for App::Config::File is actually provided
+by its grand-parent class, App::Reference.
+It creates a reference by calling App::Config::File->create(),
+blesses it into the class, calls init()
+(App::Reference->init()) which does nothing,
+and then returns the constructed Config::File object.
+
+The Config::File->create() method loads data from a configuration
+file and returns the reference to a hash.  But first it has to find
+the file and deserialize it.
+
+If the "configFile" was not specified in the arguments
+(%main::conf, in this case), the following files are searched for in
+order.  (If the script were renamed to "foo", it would look for "foo"
+variants of the files instead of "app" variants of the files.)
+
+   1. app.pl           2. config.pl
+   3. app.xml          4. config.xml
+   5. app.ini          6. config.ini
+   7. app.properties   8. config.properties
+   9. app.perl        10. config.perl
+  11. app.conf        12. config.conf
+
+By convention, "config.pl" is the config file for App CGI scripts.
+However, the first file that is found is assumed to be the relevant config file.
+If no config file is found or if it cannot be opened, an exception is thrown.
+Otherwise, the text is read in from the file and deserialized into
+a hash reference.
+
+If the "configSerializerClass" was not specified in the arguments
+(%main::conf, in this case), the file suffix for the config file
+is used to determine the Serializer class to use for deserialization.
+
+  pl          # use "eval" instead of a serializer
+  perl        # App::Serializer::Dumper (like "pl" but use a serializer)
+  xml         # App::Serializer::XMLSimple
+  ini         # App::Serializer::Ini
+  properties  # App::Serializer::Properties
+  conf        # App::Serializer::Properties
+  stor        # App::Serializer::Storable
+
+If the file is a .pl file, no serializer is implied.  It is just eval'ed.
+(It must have "$var =" as the first non-whitespace text in the file,
+where "var" is any variable name.)
+
+If a Serializer is specified or implied, a serializer is instantiated
+and the config file data is deserialized into a hash reference.
+
+The resulting hash reference is returned and stored in $context->{config}.
+
+=head2 App::Context::CGI->init()
+
+The init() method is where the CGI object is created, parsing the
+environment variables and STDIN which are
+part of the CGI runtime environment.
+
+For debugging purposes, a "debugmode" variable is checked in the 
+%args (i.e. %main::conf) to see if
+special processing with the CGI object should be performed.
+If "debugmode" is "record", the CGI objects and the %ENV hash will
+be saved to files ("debug.vars" and "debug.env", respectively).
+If "debugmode" is "replay", the current %ENV and CGI will be
+cleared and loaded from the files from a previously recorded request.
+
+Another sort of debugging is initialized if the "debug"
+variable is supplied in the %args.  This turns on a global debug
+flag ($App::DEBUG) and sets the debug scope
+(which classes or methods should produce debug output).
+
+To support migration of code, the CGI object can also be passed into
+the App->context() method as an argument, and it will be used rather
+than trying to create a new one.  However, this is not the execution
+path being described here.
+
+=head2 App::Session::HTMLHidden->new()
+
+The constructor (new()) for App::Session::HTMLHidden is actually provided
+by its grand-parent class, App::Reference.
+It creates a hash reference by calling App::Reference->create(),
+blesses it into the class, calls init()
+(App::Session::HTMLHidden->init()),
+and then returns the constructed Session::HTMLHidden object.
+
+The init() method looks at the CGI variables in the request
+and restores the session state information from the variable
+named "app.sessiondata" (and "app.sessiondata[2..n]").
+When the values of these variables are concatenated, they
+form a Base64-encoded, gzipped, frozen multi-level hash of
+session state data.  To retrieve the state data, the text
+is therefore decoded, gunzipped, and thawed (a la Storable).
+This state is stored in $session->{state} and the session
+cache is initialized to an empty hashref.
+
+=head2 cgi-bin/app and dispatching events
+
+The "app" program finally executes the following line.
+
+  $context->dispatch_events();
+
+This does everything necessary to dispatch events which are
+implied in the HTTP request, loading whatever data is needed,
+modifying it, and saving it again to await the next request.
+
+Please note that other Context implementations (i.e. Context::Modperl)
+use the same API, but they may already have database connections
+initialized, data already loaded, etc.  However, the basic
+CGI Context (Context::CGI) described here must initialize
+everything at the outset and shut it all down at the completion
+of each request.
+
+=head2 App::Context::CGI->dispatch_events()
+
+The CGI variables are examined.  Variables which start with "app.event"
+are identified as events to be handled, and they are saved for later.
+These are called "event variables".
+
+All other variables are understood to be widget attributes and they
+are saved to their respective widgets. 
+
+Variables with any of the
+"{}[]" "indexing" characters (such as "table_editor{data}[1][5]") are
+called "indexed variables".  The value is saved to the "table_editor"
+widget, which evidently has an attribute called "data" which is a
+two dimensional array.
+
+Variables without the indexing characters but 
+with at least one dot (".") in them are "dotted variables"
+of the form "widgetname.attributename".  (This is a synonym for
+"widgetname{attributename}", but it is handled more efficiently.)
+Widget names may include dots, but attribute names may not.
+Thus, the last dot separates the widget name from the attribute name.
+So "app.toolbar.savebutton.width" is the "width" attribute on the
+"app.toolbar.savebutton" widget.
+
+Variables without indexing characters or dots are "plain variables".
+If the special variable "wname" was also supplied, all plain variables
+are understood to be attributes of the $wname widget.  Otherwise,
+all plain variables are stored in the "session" widget.
+
+After all variables are stored in the Session, events are handled.
+There are two kinds of events, "user events" (such as come from
+<input type=submit> and <input type=image> tags) and "callback events"
+(such as come from <input type=hidden> tags).
+
+User events have a name that looks like one of the following.
+
+  app.event.widgetname.eventname
+  app.event.widgetname.eventname(arg1)
+  app.event.widgetname.eventname(arg1,arg2,...)
+
+These events are parsed, the appropriate widget is summoned, and the
+widget is instructed to handle the event (i.e. $w->handle_event()).
+
+Callback events have a name that looks simply like "app.event".
+The "widgetname.eventname(args)" is in the value of the variable.
+
+After all events have been handled, the context calls
+$self->display_current_widget() and then calls
+$self->shutdown() which gracefully shuts down all connections
+to repositories.
+
+=head2 App::Context::CGI->display_current_widget()
+
+The display_current_widget() method is implemented in the parent
+class, App::Context::HTML.
+
+A attribute "session.current_widget" contains the name of the current
+widget to display. 
+
+If this is not set, check the CGI variable "wname"
+(and set session.current_widget if found).
+If this is not set, check the Initialization Config (i.e. the copy
+of %main::conf, stored in the $context) for a variable named
+"defaultWname".
+If this is not set, use the $PATH_INFO, with internal "/'s"
+converted to dots (i.e. "/app/selector" => "app.selector").
+Otherwise, use "default" as the current widget
+(and set session.current_widget).
+
+Then the current widget is summoned and handed to the display_items()
+method.
+
+=head2 App::Context::CGI->display_items()
+
+The job of display items is to take the list of args, convert them
+to HTML, and print them to STDOUT with the appropriate HTTP headers
+and wrapper HTML.
+Also, depending on the %main::conf and the browser capabilities,
+the content may be compressed (gzipped).
+
+If the first argument to display_items() is a widget (which it is
+in this flow of execution), the widget's attributes are checked to
+see if any of the following are specified:
+
+  title
+  bgcolor
+  text
+  link
+  vlink
+  alink
+  leftmargin
+  topmargin
+  rightmargin
+  bottommargin
+  class
+
+Any of those attributes which are set in the widget will be propagated
+into the appropriate places in the <head> and <body> tags of the HTML
+which wraps the widget HTML.
+
+That's it.  All of the processing for a single CGI request is complete.
+All application code is wrapped up in user interface widgets
+(App::Widget::HTML) and entity widgets (App::Widget::Entity).
+The user interface widgets are mostly prepackaged, but are configured
+through the configuration file, allowing for a data-driven programming
+style on the user interface.  The entity widgets store most of their state
+in Repositories.  They also get configured
+through the config file, but they are frequently subclassed to add
+additional functionality.
+
+=cut
+

Added: p5ee/trunk/App-Context/lib/App/exceptions.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/exceptions.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,379 @@
+#!perl -w
+# run this document through perl to check its syntax
+use Pod::Checker;
+podchecker(\*DATA);
+__END__
+
+=head1 NAME
+
+App::exceptions - Programming with Exceptions
+
+=head1 INTRODUCTION
+
+Programming with Exceptions
+is a much more reliable way to prepare for unusual conditions
+than trying to handle error codes returned from functions and methods
+That is why programming with exceptions is an Enterprise Programming
+topic.  However, Perl has not always supported programming with
+exceptions, and many Perl programmers are not familiar with this
+style of programming using Perl.
+
+This document was written to explain the support within the Perl
+language for programming using exceptions in general.  It also explains
+the standards for exception programming in the App-Context framework.
+
+The short answer is that we recommend the following modules
+to assist in exception programming.
+
+  Carp
+  CGI::Carp
+  Fatal
+  Exception::Class
+  Devel::Stacktrace
+
+However, it is important to understand what each does for you,
+why, and how they all fit together.
+So for the longer answer, read on.
+
+=head1 IMPORTANCE OF EXCEPTION PROGRAMMING
+
+Exception Programming is a technique to deal with exceptional 
+conditions (i.e. errors) encountered during runtime. 
+It is contrasted with the more common technique of 
+Error Checking.
+
+Error Checking is a technique where an operation is performed.
+Then all possible error conditions are checked and handled.
+This requires the developer to address the following challenges.
+
+=over
+
+=item 1. Error Completeness
+
+The developer must consider all possible error conditions
+(difficult to foresee and consider at every level).
+
+=item 2. Error Propagation
+
+The developer must add quite a bit of additional logic
+to allow subsequent statements after the error condition
+to be skipped and the error to be propagated upward in
+the call stack to the place where
+it can be acted on appropriately.
+
+=back
+
+The problems with Error Checking is that it is so difficult
+to do and so rarely done completely. 
+Since the program runs fine when no errors are
+encountered, the developer invariably fails to put in all of
+the error checks and the accompanying error propagation logic.
+
+Exception Programming addresses these problems using the
+following methods.
+
+=over
+
+=item 1. Error Completeness
+
+Exceptions are grouped into an exception hierarchy.
+Therefore, high level code needs only make the distinctions
+between exceptions that it thinks are relevant.  If additional
+exceptions are added later by low level code, they will be
+handled in accordance with the upper levels of the exception
+hierarchy which are already known.
+
+=item 2. Error Propagation
+
+Exceptions take advantage of built-in language support
+(longjmp() in C) to unravel the call stack.  Additional
+logic is not required by the developer to propagate the
+error to a place that is prepared to handle it.
+
+=back
+
+Because Exception Programming addresses the issue of 
+software reliability (one of the Attributes of Enterprise
+Systems), it is necessarily an Enterprise Programming issue.
+
+=head1 PERL 5 LANGUAGE SUPPORT
+
+Perl did not always support exception programming.
+Even in Perl 5.6.1, the support for exception programming
+is somewhat scattered.
+The following are features of Perl 5 which are relevant
+to exception programming.
+
+=head2 die
+
+  Camel Book: Chapter 3: Functions, "die"
+  Online Doc: man perlfunc (or "perldoc perlfunc")
+
+The "die" function prints its arguments to STDERR and causes
+the program to exit.  It has some extra features, like appending
+__FILE__ and __LINE__ strings if the args don't end with a
+newline.  The biggest feature is that it may be "caught"
+if it is executed within an eval statement.
+
+Simply put, "die" is the native Perl way of "throwing" an
+exception.  The only "attributes" of the "exception" is the
+message (concatenated args) of the "die" itself.
+
+  if ($error_condition_xyz_exists) {
+      die "Error XYZ occurred";
+  }
+
+The "warn" function is similar to "die", in that it prints out
+its arguments to STDERR in the same way, but it does not try
+to exit or throw an exception in any way.  Therefore, it's not
+relevant for this discussion.
+
+  die  "I'm dying";    # print msg to STDERR and exit
+
+=head2 croak and confess
+
+  Camel Book: Chapter 7: The Standard Perl Library, "Carp"
+  Online Doc: man Carp (or "perldoc Carp")
+
+The Carp.pm module is part of the Standard Perl Library
+It allows you to throw exceptions (like "die"), but it reports
+the line number and file name from the perspective of the 
+caller of the function/method that died.
+
+This is useful for library code, so that the programmer sees
+where he invoked the function that failed rather than seeing
+where within that function the failure occurred.
+
+  use Carp;
+
+  croak "We're outta here!";     # like "die", but line # from caller
+  confess "It was my fault: $!"; # like "croak" but with stack trace
+
+Using "croak" to throw an exception references the line # and
+file name of the caller.
+
+Using "confess" to throw an exception causes a 
+stack trace to be printed also.
+
+=head2 CGI::Carp
+
+  Online Doc: man CGI::Carp (or "perldoc CGI::Carp")
+
+If you are developing perl scripts which will be run
+by a web server, the STDERR stream is usually redirected
+the web server error log.  However, the output generated
+by "die" is not formatted nicely, with a datetime stamp
+and filename, as is customary with error log entries.
+
+The CGI::Carp package replaces die, croak, and confess
+with versions which work the same but format the output
+a little more nicely for the web server error log.
+You can even direct fatal errors to the browser.
+
+  use CGI::Carp;
+
+  die  "I'm dying";              # print msg to log and exit
+  warn "I'm confused";           # print msg to log
+  croak "We're outta here!";     # like "die", but line # from caller
+  confess "It was my fault: $!"; # like "croak" but with stack trace
+  carp "It was your fault!";     # like "warn", but line # from caller
+
+  use CGI::Carp qw(fatalsToBrowser);
+  die "Fatal error messages are now sent to browser";
+
+=head2 $!
+
+  Camel Book: Chapter 2: The Gory Details/Special Variables, $!
+  Online Doc: man perlvar (or "perldoc perlvar")
+
+If used in a string context, yields the error string
+from the last system call error in the currently executing perl 
+interpreter.
+
+You shouldn't depend on $! being 
+anything in particular unless you've gotten a specific error
+indicating a system error.
+
+So when you get a system call error returned from a perl function
+(system calls usually relate to files, networking,
+processes, or interprocess communication), you can check $!.
+
+If you want to use good exception programming techniques, every
+perl function which can fail from a system call error should
+be checked for its return value so that an exception may be
+thrown.
+
+  $file = "foo.txt";
+  open(FILE, "< $file") || die "Error opening [$file]: $!";
+
+Of course, if your program's requirements allow you to
+handle the error locally without
+throwing an exception, you are welcome to.
+However, every possible error needs to be thought about
+and accounted for.
+
+  $file = "foo.txt";
+  if (open(FILE, "< $file")) {  # if file doesn't exist, that's ok
+      @data = <FILE>;
+      close(FILE);
+  }
+
+=head2 eval
+
+  Camel Book: Chapter 3: Functions, "eval"
+  Online Doc: man perlfunc (or "perldoc perlfunc")
+
+Eval serves as Perl's version of a "try {}" block.
+
+If a "die" (an exception) occurs within an "eval", the program
+is not terminated, only the "eval".  All of the code
+that was eval'ed, after the exception, is skipped.
+
+Eval has two syntaxes, "eval EXPR" and "eval BLOCK".
+
+The "eval EXPR" syntax causes the code contained in the 
+EXPR expression to be compiled every time the 
+statement is executed during runtime.
+
+  eval "&do_big_function();";
+  $code = "&do_another_big_operation();";
+  eval $code;
+
+The "eval BLOCK" syntax causes the code contained in the
+BLOCK to be compiled only once (at script compile time),
+so it is much more efficient and appropriate for 
+exception programming.
+(Please note the semi-colon that must follow the BLOCK.)
+
+  eval {
+      &do_big_function();
+  };
+
+If any exception ("die") is thrown within the do_big_function(),
+the program will not terminate.  Control will simply be returned
+to the end of the eval block.
+
+=head2 $@
+
+  Camel Book: Chapter 2: The Gory Details/Special Variables, $@
+  Online Doc: man perlvar (or "perldoc perlvar")
+
+The is the Perl syntax error message from the last "eval" command.
+Alternatively, it is the message of an exception that was thrown
+(using "die").
+If null, the last eval was parsed and executed correctly, with
+no exceptions.
+
+Thus, perl exception programming can be done with the following.
+
+  eval {
+      &do_big_function();
+  };
+  if ($@) {
+      # handle the exception ($@ is the exception message)
+  }
+
+  sub do_big_function {
+      ...
+      if ($error_condition_xyz_exists) {
+          die "Error XYZ occurred";
+      }
+      ...
+  }
+
+=head2 $SIG{__DIE__}
+
+  Camel Book: Chapter 2: The Gory Details/Special Variables, %SIG
+  Online Doc: man perlvar (or "perldoc perlvar")
+
+This handler is not necessary to know about to do exception 
+programming in Perl.  However, it may be used by modules that assist
+in exception handling tasks.
+
+The %SIG hash contains references to subroutines which are called
+in response to signals received by the process.  "__DIE__" is a
+special internal hook which is not really an external signal.
+
+So if you desired to do some additional processing between the
+time that the "die" exception was thrown and the time it was
+handled, you could replace the $SIG{__DIE__} handler.
+
+  $SIG{__DIE__} = sub {
+      # do something (@_ are the args of the "die")
+  };
+
+=head2 caller
+
+  Camel Book: Chapter 3: Functions, "caller"
+  Online Doc: man perlfunc (or "perldoc perlfunc")
+
+The "caller" function allows you to examine the call stack
+in order (for example) to print stack traces.
+
+=head2 Weaknesses in the Native Perl Exception Support
+
+The eval/die pair provides the critical language support
+necessary for Error Propagation. 
+
+However, the single
+attribute of an exception, the message, leaves the
+developer without an exception hierarchy which would
+allow him to ensure Error Completeness in his
+exception handling.
+
+Furthermore, the Perl functions themselves must be
+checked for errors rather than throwing exceptions.
+
+=head1 EXCEPTION PROGRAMMING USING Fatal.pm
+
+Causes all of the perl functions to throw exceptions
+rather than simply return error codes or set error
+flags.
+
+=head1 EXCEPTION PROGRAMMING USING Error.pm
+
+Introduces the ability to have an Exception Class
+(not just a message) and to use "try/catch"
+syntax.
+
+It does this be defining try() and catch() subroutines
+with appropriate prototypes, using the "{}" blocks
+as closures (or anonymous subroutines).  See the following
+references.
+
+  Camel Book: Chapter 2: The Gory Details, Subroutines, Prototypes
+  Camel Book: Chapter 4: References and Nested Data Structures, Using Hard References, Closures
+
+However, you must be very careful in the placement of
+your semi-colons using the try/catch syntax provided by
+Error.pm or your
+module will leak memory (very bad in a mod_perl context).
+
+=head1 EXCEPTION PROGRAMMING USING Exception::Class
+
+Introduces the capability to collect exception
+classes easily in a class hierarchy.  This helps
+address the issue of Error Completeness.
+
+=head1 EXCEPTION PROGRAMMING USING Devel::Stacktrace
+
+Adds the capability to print out more detailed
+stack trace information than was possible with
+"confess".
+
+=head1 FURTHER RESEARCH
+
+An excellent section on Exception Handling in Perl
+exists in the mod_perl Guide.
+
+  http://perl.apache.org/guide/perl.html#Exception_Handling_for_mod_perl
+
+You can read up on future directions
+for Perl and the evolving exception support here.
+
+  http://www.perl.com/pub/a/2002/01/15/apo4.html?page=3
+  http://dev.perl.org/rfc/88.html
+  http://nntp.perl.org/group/perl.perl6.language.errors
+
+=cut
+

Added: p5ee/trunk/App-Context/lib/App/faq.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/faq.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,182 @@
+#!perl -w
+# run this document through perl to check its syntax
+use Pod::Checker;
+podchecker(\*DATA);
+__END__
+
+=head1 NAME
+
+App::faq - App-Context Frequently Asked Questions
+
+=head1 INTRODUCTION
+
+This is the FAQ for the
+App-Context software framework
+(a variant of the Perl 5 Enterprise Environment).
+You can find out more background to the project on the web.
+
+  http://www.officevision.com/pub/p5ee
+  http://p5ee.perl.org
+
+=head1 GENERAL
+
+=head2 Why should I use App-Context rather than J2EE or .NET?
+
+Perhaps it's because you prefer writing in Perl?
+But besides that, there are other reasons.
+
+Java's promise of "write once, run anywhere" is actually
+better fulfilled by Perl than Java.
+
+The .NET CLR's promise of "any language, one runtime
+environment" is great.  But Parrot will do for dynamically
+typed languages what the .NET CLR does for statically typed
+languages.  (See http://www.parrotcode.org/faq/.)
+And Perl6 will support the CLR as well.
+
+I looked around at the state of various cross-platform application
+runtime environments, and saw that the most pervasive execution 
+environments, available across many platforms were: 
+Perl (on servers), Java (on servers and browsers), 
+and Javascript (on browsers).  Each of these technologies
+holds the promise, to some varying degree, of
+"write once, run anywhere". ".Net" was not yet on the scene,
+but even when it arrived, the promise of proper cross-platform
+support for .Net was a long way off and altogether uncertain.
+
+Perl has excellent support even for unprivileged accounts
+at ISP's, whereas Servlet support is hard to come by unless
+you own the machine (or you go to a very specialized ISP).
+Also, Perl offers several ways to do web applications: CGI for
+unprivileged, quick and dirty implementations, and mod_perl
+for high performance implementations when you have full control
+over the web server (also PerlEx, FastCGI, etc.).
+
+If you have a desire to program in Java and you like the API's
+that Sun (and others) have created, you should probably focus
+on Java. I think that things could be a lot simpler (or maybe
+higher level) than the J2EE specifies them.
+
+It seemed that the one thing that Perl was lacking was
+a blueprint for large-scale development and deployment of 
+high-performance, high-availability systems (i.e. enterprise 
+systems) along with guides of discipline for coding and 
+documentation.  The App-Context framework fills this gap.
+
+So that's the explanation of "why App-Context?"
+
+For an explanation of "why not App-Context?" you might consider that it
+is still largely vaporware.
+
+=head2 How well does the App-Context fit into a .NET technical strategy?
+
+It may seem that App-Context is most at home with the following technologies.
+
+  * Perl, Linux, Apache, CGI, and MySQL.
+
+However, the App-Context framework abstracts much of the 
+runtime environment, so that it is just as easy to use:
+
+  * Perl, Windows NT, IIS, ISAPI, and SQLServer.
+
+So the question becomes, "How well does Perl fit into a .NET
+technical strategy?"
+
+Although Perl is not a core .NET language from Microsoft's
+perspective, the following three considerations would suggest
+that Perl is not outside of a .NET technical strategy.
+
+ 1. Perl integration with Windows and .NET is substantial 
+    (using the ActiveState port of Perl)
+    http://www.activestate.com/Products/ActivePerl/
+
+ 2. Perl's predominant SOAP implementation is very mature
+    http://www.soaplite.com/
+
+ 3. When Perl 6 is complete, both Perl 5 and Perl 6 will be able
+    to run on the .NET CLR.
+    http://www.parrotcode.org/faq/
+
+=head2 What is the relation between App-Context and mod_perl?
+
+The people who have been developing and working on mod_perl have done
+an incredible service to Enterprise Perl in general, and therefore
+the App-Context in particular.  Other efforts that dramatically enhance
+Enterprise Perl are SOAP projects, XML projects, DBD/DBI::*,
+Templating projects, etc.  These are all making dramatic contributions,
+and they need not change anything they are doing in order to continue
+to do so.
+
+On the contrary, the responsibility is on the designers of the App-Context
+to accommodate and incorporate these many enterprise-class technologies
+into an integrates whole.  Browse the classes envisioned for App-Context
+to see one way that these might fit together.  Take
+special note of the "Classes (Planned)" at the bottom of the 
+"All Classes" frame.
+
+  http://www.officevision.com/pub/p5ee/software/htdocs/api/
+
+As for mod_perl, it would seem to be the container of choice for
+web applications and SOAP services.  
+
+  http://www.officevision.com/pub/p5ee/software/htdocs/Appx/Blue/Context.html
+
+There is no need for the mod_perl project to explicitly 
+integrate with App-Context.  However, in the spirit of community, 
+as the App-Context grows in its capabilities, I would imagine a 
+natural cross-fertilization of ideas would occur so that if App-Context needed
+any specific feature in mod_perl it would be implemented without
+too much trouble.
+
+However, App-Context reaches further than just running in a mod_perl Context.
+App-Context is equipped with (when they are written, of course) a variety of 
+Context classes which allow App-Context software to run in many other Contexts 
+besides mod_perl.
+
+=head2 What does it mean for App-Context to support Perl 5.5.3 if some of its components require a higher version of Perl?
+
+The App-Context is like a software backplane
+for many services required by an enterprise application.  Into that
+backplane plug the App-Context Services.  There may be many implementations
+of each of the App-Context Services, making for an almost limitless array
+of possible combinations.  (Hopefully, favorites will emerge.)
+
+The Context is a Core Service, like Session and Config.
+(A Core Service is one that is not derived from App::Service
+but maintains the concept of "a pluggable implementation of an 
+abstract service".)  An examination of the App::Context
+documentation will show that there are many Contexts from which
+the implementer may choose to deploy the software, and the software
+could reasonably run on all of them.  The fact that (the envisioned)
+App::Context::Modperl2 depends on 5.6.0 does not invalidate
+the fact that the App-Context depends only on 5.5.3.  Implementers who
+choose to deploy with Services that have higher Perl version 
+dependencies must of course satisfy those dependencies.
+
+The important thing to realize is that there is some combination of
+implementations of Services which will run on 5.5.3.  Thus, the
+implementer who is stuck with 5.5.3 on a platform does indeed have a
+set of possible combinations of Services which will work.
+
+The dependency on Perl version is not the only issue like this.
+Some modules are dependent upon certain operating systems.
+It is acceptable for a Service implementation to use these OS-specific
+functions as long as there is some other Service implementation 
+(perhaps lower performing) which meets the cross-platform requirement.
+
+i.e. App::Context::Modperl2 may require 5.6.0, but
+App::Context::Modperl and App::Context::CGI will
+both run on 5.5.3.
+
+Sometimes when we think about Enterprise Systems, we think about
+big budget projects with the latest new hardware.  My experience 
+with customers who are large enterprises is that they have an 
+incredible mish-mash of systems and legacy environments.  I envision 
+that App-Context software could be installed on every platform they own 
+(isn't Perl almost the most-ported language on the planet?).  
+That is why I believe that App-Context must support 5.5.3 (or perhaps 
+earlier, but I won't go there yet until I see a real need to
+and understand exactly what I would be giving up).
+
+=cut
+

Added: p5ee/trunk/App-Context/lib/App/installguide.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/installguide.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,229 @@
+#!perl -w
+# run this document through perl to check its syntax
+use Pod::Checker;
+podchecker(\*DATA);
+__END__
+
+=head1 NAME
+
+App::installguide - App Installation Guide
+
+=head1 INTRODUCTION
+
+This is the Installation Guide to the
+App (Perl 5 Enterprise Environment).
+You can find out more background to the project on the web.
+
+  http://www.officevision.com/pub/p5ee
+  http://p5ee.perl.org
+
+Installation of the App requires the following:
+
+ * install Perl (at least 5.5.3) (5.005_03)
+   (you can test this by typing "perl -v")
+ * install Apache or other web server
+ * install dependent Perl modules from CPAN
+ * install App software
+
+We will discuss the last item first, because it is assumed
+that most people know how to do the first three or they 
+are already done.
+
+=head1 SET UP THE ENVIRONMENT
+
+You could just install all of the software into "/usr/local" or
+wherever your Perl is installed.  In that case, skip this section.
+
+If however, you are setting up a development environment, or
+if you wish to install multiple versions of the App software,
+it is advisable you choose an approach as follows.
+
+=head2 Set Up a Development Environment (Unix)
+
+Choose a directory that will be the base of all App
+environments (i.e. /usr/mycompany, any base directory will do).
+
+  /usr/mycompany
+
+Create a subdirectory for each separate developer/tester.
+You may wish to choose groups rather than users (i.e. "devel", "qagroup").
+(In this case, you would have several developers working in
+one directory tree.  This may cause more conflicts between
+developers during development, but the
+conflicts get worked out more quickly than when developers
+work in separate directories.)
+
+  /usr/mycompany/spadkins
+  /usr/mycompany/joe
+  /usr/mycompany/marysue
+  /usr/mycompany/devel
+  /usr/mycompany/qagroup
+
+These are independent development "sandboxes".
+Later, when we start making releases of the software (which includes the App
+framework), we will create other environment directories like this.
+
+  /usr/mycompany/0.5.0
+  /usr/mycompany/0.5.1
+  /usr/mycompany/1.0.0
+  /usr/mycompany/2.17.10
+
+All of these directories will have their own self-contained installation
+of software.  Named versions (i.e. "test", "qa", "prod") are simply
+symbolic links to the particular version to which they currently apply.
+
+In your chosen development directory, you should set the permissions
+to allow access to be granted by group.
+
+  chgrp -R spadkins /usr/mycompany/spadkins  # all files and dirs owned by group
+  chmod 775 `find /usr/mycompany/spadkins -type d -print` # dirs writable by the group
+  chmod g+s `find /usr/mycompany/spadkins -type d -print` # setgid bit keeps files in the group
+
+Within each directory, you should create a default set of subdirectories.
+
+  cd /usr/mycompany/spadkins
+  mkdir src lib bin man etc include src/tar
+
+You should set up in your ".profile" some appropriate variables.
+
+  PREFIX=/usr/mycompany/spadkins; export PREFIX
+  PATH=$PREFIX/bin:$PATH; export PATH
+  LD_LIBRARY_PATH=$PREFIX/lib:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
+  LIBPATH=$PREFIX/lib:$LIBPATH; export LIBPATH  # for AIX? (instead of LD_LIBRARY_PATH)
+  MANPATH=$PREFIX/man:$MANPATH; export MANPATH
+
+Note: If no initial MANPATH was set, setting the MANPATH this way
+could inhibit the "man" command
+from finding all of the standard "man" pages.  You may need to create
+an initial MANPATH something like this and then add the $PREFIX/man
+directory to it.
+
+  MANPATH=`find /usr /opt /man -type d -name man -print 2> /dev/null`
+  MANPATH=`echo $MANPATH | sed 's/ /:/g'`
+  export MANPATH
+
+Note: It may be similar for LD_LIBRARY_PATH, and you may need to set an
+initial LD_LIBRARY_PATH something like this.
+
+  LD_LIBRARY_PATH=`find /usr /opt /lib -type d -name lib -print 2> /dev/null`
+  LD_LIBRARY_PATH=`echo $LD_LIBRARY_PATH | sed 's/ /:/g'`
+  export LD_LIBRARY_PATH
+
+Now log out and log in again so that your ".profile" variables
+are in your environment.
+
+=head2 Set Up a Development Environment (Windows)
+
+See L<App::installguide::win32>.
+
+=head1 INSTALL DEPENDENT SOFTWARE
+
+=head2 Install Dependent Modules from CPAN
+
+  perl -MCPAN -e shell
+  cpan> install Date::Parse
+  cpan> install Date::Format
+  cpan> install Data::Dumper
+  cpan> install Compress::Zlib
+  cpan> install MIME::Base64
+  cpan> install Storable
+  cpan> install Exception::Class
+  cpan> install Class::MethodMaker
+  cpan> install Hook::LexWrap
+  cpan> install Aspect
+  cpan> exit
+
+If anyone finds other dependent modules, please let me know.
+
+=head1 GET App SOFTWARE
+
+=head2 Get App From CPAN
+
+The App is not yet on CPAN.
+Try one of the other methods.
+
+=head2 Get App from CVS (to develop App)
+
+You should use this method if you *do* have commit access
+on the App CVS repository.  (Note, substitute your CVS
+user id for "LOGIN" below.)
+
+  cd $PREFIX/src
+  cvs -d :pserver:[email protected]:/cvs/public login
+  [enter your perl.org password]
+  cvs -d :pserver:[email protected]:/cvs/public co p5ee
+
+Later, when you want to refresh your directory with the latest software
+from CVS, you can repeat the same commands or you can do the following.
+
+  cd $PREFIX/src/p5ee
+  cvs update -dP
+
+See a CVS document to find out how to create, delete, and modify files
+and then submit changes.
+
+=head2 Get App from CVS (anonymous, read-only access to latest App)
+
+You should use this method if you do *not* have commit access
+on the App CVS repository but you do want to stay up to date with the
+latest App software (recommended, because there are no releases yet).
+
+  cd $PREFIX/src
+  cvs -d :pserver:[email protected]:/cvs/public login
+  [press enter at the password prompt]
+  cvs -d :pserver:[email protected]:/cvs/public co p5ee
+
+Later, when you want to refresh your directory with the latest software
+from CVS, you can repeat the same commands or you can do the following.
+
+  cd $PREFIX/src/p5ee
+  cvs update -dP
+
+The "cvs update" method is the preferred way to get updates.
+
+=head2 Get App from a Snapshot
+
+If you do not have CVS on your system, you can still get reasonably 
+recent sources from http://cvs.perl.org/snapshots/p5ee/.
+
+  cd $PREFIX/src
+  wget -O tar/p5ee-latest.tar.gz http://cvs.perl.org/snapshots/p5ee/p5ee-latest.tar.gz
+  gunzip < tar/p5ee-latest.tar.gz | tar xvf -
+
+If you don't have "wget" (http://www.gnu.org/software/wget/wget.html),
+you can use Perl's own LWP.
+
+  cd $PREFIX/src
+  perl -MLWP::Simple -e 'getstore("http://cvs.perl.org/snapshots/p5ee/p5ee-latest.tar.gz", "tar/p5ee-latest.tar.gz")'
+  gunzip < tar/p5ee-latest.tar.gz | tar xvf -
+
+=head1 INSTALL App SOFTWARE
+
+=head2 Install Perl Modules, Man Pages, HTML Pages
+
+  cd $PREFIX/src/p5ee/App
+  make
+  make test    (these may or may not work. the tests themselves are under development.)
+  make install
+
+=head2 Edit Main Config File
+
+You will need to do this one time.
+
+  cd $PREFIX/src/p5ee/App-/cgi-bin
+  cp demo.conf p5ee.conf
+  vi p5ee.conf
+  # edit the following lines:
+  #   * perlinc       = list of perl include paths
+  #   * scriptDir     = absolute path for directory which the "p5x" script will be in
+  #   * scriptUrlDir  = path from http://localhost to the scriptDir
+  #   * htmlDir       = absolute path for the "htdocs" directory
+  #   * htmlUrlDir    = path from http://localhost to the htmlDir
+  #   * ttTemplateDir = apsolute path for the "templates" directory
+
+=head2 Make HTML Pages Visible on the Webserver
+
+=head2 Make CGI Programs Visible on the Webserver
+
+=cut
+

Added: p5ee/trunk/App-Context/lib/App/installguide/hosted.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/installguide/hosted.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,401 @@
+
+=head1 NAME
+
+App::installguide::hosted - Instructions on installing the App::Context framework in a web-hosting (non-root) environment
+
+=head1 DESCRIPTION
+
+These are instructions on installing the App::Context framework in a web-hosting (non-root) environment.
+
+=head1 ASSUMPTIONS
+
+ * You get command line access but not root.
+ * You have access to a MySQL database engine (and permissions to create at least 3 databases)
+
+=head1 SET UP THE CPAN SHELL
+
+Installing software from CPAN into a non-system area requires a little setup.
+
+ * Find CPAN/Config.pm and make a local copy of it to MyConfig.pm
+ * Modify MyConfig.pm to use local directories
+
+The first thing to do is to find CPAN/Config.pm.
+
+ > which perl
+ /usr/bin/perl
+
+Since perl is installed in /usr/bin, the perl libraries are most likely stored in /usr/lib/perl5.
+
+ > find /usr/lib/perl5 -name Config.pm -print
+ /usr/lib/perl5/site_perl/5.8.7/x86_64-linux/Template/Config.pm
+ /usr/lib/perl5/site_perl/5.8.7/Apache/Admin/Config.pm
+ /usr/lib/perl5/5.8.5/CPAN/Config.pm
+ /usr/lib/perl5/5.8.5/Net/Config.pm
+ /usr/lib/perl5/5.8.7/x86_64-linux/Encode/Config.pm
+ /usr/lib/perl5/5.8.7/x86_64-linux/Config.pm
+ /usr/lib/perl5/5.8.7/CPAN/Config.pm
+ /usr/lib/perl5/5.8.7/Net/Config.pm
+ 
+Now make a copy of CPAN::Config.
+
+ mkdir ~/.cpan
+ mkdir ~/.cpan/CPAN
+ cp /usr/lib/perl5/5.8.7/CPAN/Config.pm ~/.cpan/CPAN/MyConfig.pm
+
+Now edit it.
+
+ vi ~/.cpan/CPAN/MyConfig.pm
+
+There might be lines like the following.
+
+  'build_dir' => q[/root/.cpan/build],
+  'cpan_home' => q[/root/.cpan],
+  'histfile' => q[/root/.cpan/histfile],
+  'keep_source_where' => q[/root/.cpan/sources],
+  'makepl_arg' => q[],
+  'make_install_arg' => q[UNINST=1],
+  'mbuildpl_arg' => q[],
+
+Change them to something like the following.
+
+  'build_dir' => q[/home/username/.cpan/build],
+  'cpan_home' => q[/home/username/.cpan],
+  'histfile' => q[/home/username/.cpan/histfile],
+  'keep_source_where' => q[/home/username/.cpan/sources],
+  'makepl_arg' => q[PREFIX=/home/username],
+  'make_install_arg' => q[],
+  'mbuildpl_arg' => q[install_base=/home/username],
+
+Then fire up the CPAN shell and install something. Then verify that it installed.
+
+   # perl -MCPAN -e shell
+   cpan> install App::Options
+   cpan> exit
+   # find ~/lib -name Options.pm -print
+   /home/username/lib/perl5/site_perl/5.8.7/App/Options.pm
+
+Yay. Success. We used the CPAN shell to install modules into our private perl
+library directory.
+
+=head1 A REASONABLE DEVELOPMENT PROCESS AND PROMOTION PATH
+
+The advice of this section is highly subject to preference. What is described
+here is a reasonable way to manage the development process of promoting code
+changes and database changes from development through test into production.
+
+We use one development environment. An "environment" is a top-level directory
+which houses an instance of the application completely independent from the
+next instance of the application. (An alternate style for slightly bigger
+projects and teams would be to have one development "sandbox" environment
+per developer, but I'll skip that here.)
+The development environment points to the development database.
+
+All environments that are not development environments are numbered
+releases (or release candidates) (i.e. "1.0.0").  A numbered release
+candidate of a web application is referred to as a test environment.
+It is pointed to the test database until
+all tests are completed and the release candidate is approved.
+Then the release candidate is pointed to the production database, and
+additional tests are performed that are not destructive to the data.
+
+When it passes these final tests, it ceases to be a test environment
+any long, and it becomes the latest production environment.
+A symbolic link is changed in order to point the "production" web
+application to the latest numbered version.
+
+=head1 PREPARING YOUR SOFTWARE ENVIRONMENT DIRECTORIES
+
+First we choose a base direction where all software environment
+directories will live.
+
+   export PREFIX_BASE=$HOME/app
+
+[Note: If you were doing this on a server where you had access to space
+outside the home directory, you might make this something like
+"/usr/mycompany" instead.]
+
+Next, we prepare the environments.
+We will assume that we are preparing a "devel" environment,
+a single numbered release candidate "1.0.0" environment, and a symbolic
+link for production that points to the "1.0.0" environment.
+
+   mkdir $PREFIX_BASE
+   mkdir $PREFIX_BASE/devel
+   mkdir $PREFIX_BASE/devel/etc
+   mkdir $PREFIX_BASE/devel/etc/app
+   mkdir $PREFIX_BASE/devel/bin
+   mkdir $PREFIX_BASE/devel/lib
+   mkdir $PREFIX_BASE/devel/src
+   mkdir $PREFIX_BASE/devel/data
+   mkdir $PREFIX_BASE/1.0.0
+   mkdir $PREFIX_BASE/1.0.0/etc
+   mkdir $PREFIX_BASE/1.0.0/etc/app
+   mkdir $PREFIX_BASE/1.0.0/bin
+   mkdir $PREFIX_BASE/1.0.0/lib
+   mkdir $PREFIX_BASE/1.0.0/src
+   mkdir $PREFIX_BASE/1.0.0/data
+   ln -s $PREFIX_BASE/1.0.0 $PREFIX_BASE/prod
+
+=head1 CONFIGURE YOUR LOGIN ENVIRONMENT
+
+Investigate what the "lib" directories are on the system and decide which of those
+directories needs to be in the LD_LIBRARY_PATH (search path for libraries).
+
+   # ls -ld /lib /*/lib /*/*/lib /*/*/*/lib
+
+Investigate what the "man" directories are on the system and decide which of those
+directories needs to be in the MANPATH (search path for "man" pages).
+
+   # ls -ld /man /*/man /*/*/man /*/*/*/man
+
+Make sure we have something intelligent for the following variables in "~/.bash_profile".
+
+   export PATH=$PATH:$HOME/bin
+
+   export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib
+   export MANPATH=/man:/usr/man:/usr/share/man:/usr/local/man:/usr/local/share/man
+   export PERL5LIB=$HOME/lib/perl5:$HOME/lib/perl5/site_perl
+
+   . prefix $HOME/app/devel
+
+   set -o vi
+
+Note: The prefix script comes with the App::Options distribution. It has been
+installed in $HOME/bin.  The "prefix" script is bash-compatible and ksh-compatible.
+It enhances the PATH's that have been set as appropriate.
+
+Note 2: "set -o vi" is a bash setting I like to make command-line editing like
+the vi-style of ksh. Leave this out if you like the default emacs-style
+command-line editing.
+
+Then log out and log back in.  Test that each variable had its desired effect.
+
+   # which prefix
+   # man ls
+   # man App::Options
+   # perl -MApp::Options -e 'print $App::Options::VERSION, "\n";'
+
+=head1 INSTALL THE SOFTWARE
+
+   # perl -MCPAN -e shell
+   cpan> install App::Context
+   cpan> install App::Repository
+   cpan> install App::Widget
+   cpan> exit
+
+If any distribution fails to build (or any of the distributions they depend on),
+exit the CPAN shell immediately and try to build manually.
+
+For instance, App::Context depends on Devel::StackTrace.  If that module fails
+to install, then App::Context will fail.  Exit the CPAN shell and build it by
+hand.
+
+   cd ~/.cpan/build/Devel-StackTrace*
+   perl Makefile.PL PREFIX=/home/username
+   make
+   make test
+   make install
+
+Or if the distribution uses Module::Build, you may do the following.
+
+   perl Build.PL install_base=/home/username
+   ./Build
+   ./Build test
+   ./Build install
+
+Sometimes a distribution fails some of the tests.  If it does, the CPAN shell
+will not install it.  When you build it manually (as shown above), you may
+decide that it is an error in the test suite rather than an error in the
+modules themselves.  In this case, you can continue with the "install" step.
+Then reenter the CPAN shell and install the next module.
+
+IMPORTANT: If anyone discovers problems with these instructions or the
+distributions related to the App::Context framework, please report them to me:
+
+   [email protected]
+
+[I want to make this framework dirt simple to set up and use. -- spa]
+
+=head1 SETTING UP A MySQL DATABASE
+
+This will vary depending on your web hosting provider (and presumes they support
+the use of MySQL databases).  I went to a control panel and did all the setup.
+(This is all just an example of how I did it so that I can refer to this in later
+setup documentation.  You will probably do this differently.)
+
+I created three databases: "devel", "test", and "prod".  The control panel
+prepended my hosting username, so they ended up being called "username_devel",
+"username_test", and "username_prod".
+
+Then I created three users: "dbview", "dbuser", and "dbadmin".  Again, the control
+panel prepended my hosting username, so they ended up being called
+"username_dbview", "username_dbuser", and "username_dbadmin".  I gave them
+appropriate passwords and recorded what they were for future reference.
+
+Then I went through each combination of database and database-user to assign
+permissions to each.  I assigned all permissions to "username_dbadmin",
+"select/insert/update/delete" permissions to "username_dbuser" and only "select"
+permissions to "username_dbview".
+
+I was then able to use the web-based database administration tool, "phpMyAdmin".
+However, I prefer to do things from the command line.
+
+The next thing I did was put my MySQL login credentials into the $HOME/.my.cnf file.
+
+   [client]
+   user            = username_dbadmin
+   password        = my_password_here
+   host            = localhost
+
+   [mysql]
+   database        = username_devel
+
+Then it is *very* important to set the permissions on this file.
+
+   chmod 600 $HOME/.my.cnf
+
+This will keep anyone from reading the contents of the file (which contains your 
+database password). Then you should be able to log in directly with the mysql
+command line client.  Some sample commands are shown, but it is assumed that
+you will read the MySQL documentation and know what you are doing.
+
+   # mysql
+   Welcome to the MySQL monitor.  Commands end with ; or \g.
+   Your MySQL connection id is 1742668 to server version: 4.1.20-standard-log
+
+   Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
+
+   mysql> \s                             # show connection status
+   mysql> show databases;                # show what databases defined
+   mysql> show processlist;              # show all connections to the database
+   mysql> show tables;                   # show all tables in this database
+   mysql> use username_test;             # change to another database
+   mysql> show tables;                   # show all tables in this database
+   mysql> use username_prod;             # change back to the first database
+   mysql> show tables;                   # show all tables in this database
+   mysql> create table foo (foo_id integer not null auto_increment primary key,
+          foo_dt date, foo_name varchar(255), foo_num integer) engine=MyISAM;
+   mysql> show tables;
+   mysql> drop table foo;
+   mysql> create table foo (foo_id integer not null auto_increment primary key,
+          foo_dt date, foo_name varchar(255), foo_num integer) engine=InnoDB;
+   mysql> describe foo;
+   mysql> show table status like 'foo';
+   mysql> show indexes from foo;
+   mysql> insert into foo (foo_dt, foo_name, foo_num) values ('2006-10-08','yowee',7);
+   mysql> insert into foo (foo_dt, foo_name, foo_num) values ('2006-09-28','yowza',2);
+   mysql> select * from foo;
+   mysql> update foo set foo_num = 5 where foo_name = 'yowza';
+   mysql> select * from foo;
+   mysql> delete from foo where foo_dt = '2006-10-08';
+   mysql> select * from foo;
+   mysql> exit
+
+=head1 SET UP THE FRAMEWORK TO READ THE DATABASE
+
+=head2 CREATE app.conf
+
+There are two kinds of configuration files in an application
+written for the App::Context framework: app.conf and app.pl.
+
+The "app.conf" file is the low-level configuration file.
+"app.conf" is sometimes called the "options file" because
+it is read by App::Options.
+It contains parameters which are specific to the deployment
+rather than to the structure of the application. 
+It can be thought of as a "deployment descriptor".
+
+For our purposes, the only thing unique about our installation
+is the database connection information.
+
+   vi $PREFIX/etc/app/app.conf
+
+      dbhost = localhost
+      dbname = username_prod
+      dbuser = username_dbuser
+      dbpass = my_password_here
+
+   chmod 600 $PREFIX/etc/app/app.conf
+
+=head2 CREATE app.pl
+
+The "app.pl" file is the Application Configuration file.
+This is where you define (and assemble) Services (i.e. components)
+in the App::Context framework.
+
+When an application is developed, a file like "app.pl" is part of the source
+code of that application.  This file is not usually modified at the time
+it is deployed along with supporting code into production.
+
+For our example, we configure the Repository named
+"dbprod" as a service in the "App::Repository::MySQL" class.
+Then we configure the "default" Repository as an alias for "dbprod".
+
+   vi $PREFIX/etc/app/app.pl
+
+      $conf = {
+        Repository => {
+          default => {
+            alias => "dbprod",
+          },
+          dbprod => {
+            class => "App::Repository::MySQL",
+          },
+        },
+      };
+
+=head2 TEST THE CONNECTION
+
+With the App-Context distribution comes a generic utility, "app", that can
+be used to exercise any configured service.
+
+Try the following.
+
+   app Repository default get_rows foo
+
+"app" takes the following arguments.
+
+   1. The service type (here, it is "Repository")
+   2. The service name (here, it is "default")
+   3. The method to invoke on the service
+   4+ The arguments to the method
+
+Then it prints out whatever is returned from the method.
+
+   # app Repository default get_rows foo
+   $data = [
+     [
+       '2',
+       '2006-09-28',
+       'yowza',
+       '5'
+     ]
+   ];
+
+All programs that are built using the framework (with App-Options, App-Context,
+and App-Repository) (such as "app") get a number of built-in features for free. 
+You can experiment with the following.
+
+   app --help
+   app --debug_options=3
+   app --debug_conf
+   app --debug_sql Repository default get_rows foo
+   app --trace Repository default get_rows foo
+   
+=head1 YOUR FIRST WEB APPLICATION
+
+=head1 ACKNOWLEDGEMENTS
+
+ * Author:  Stephen Adkins <[email protected]>
+ * License: This is free software. It is licensed under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<App::quickstart>,
+L<App::installguide>,
+L<App::installguide::win32>,
+L<App::Options>, L<App::Context>, L<App::Repository>,
+L<App::Widget>
+
+=cut
+

Added: p5ee/trunk/App-Context/lib/App/installguide/win32.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/installguide/win32.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,241 @@
+#!perl -w
+# run this document through perl to check its syntax
+use Pod::Checker;
+podchecker(\*DATA);
+__END__
+
+=head1 NAME
+
+App::installguide::win32 - Installation Guide for Perl Software on Win32 System
+
+=head1 INTRODUCTION
+
+These is a general Installation Guide for installing Perl software on
+the Microsoft Windows platform.  The emphasis is on web and database applications
+in Perl.
+
+This document is motivated by helping people install the
+App-Context Framework (comprised of
+App-Context, App-Options, App-Repository, and App-Widget).
+However, most of the information here is useful regardless of what Perl modules
+you are installing.
+
+You should also read through the general Installation Guide (App::installguide) and
+understand how the software would be installed on Unix/Linux
+before consulting this specialized Win32 guide. 
+
+This guide will predominantly focus on how to get
+up and running on a plain vanilla Windows system
+for demonstration or development purposes.
+The focus here is not on optimized server installation on Windows
+servers, although the instructions may still be useful.
+
+These instructions assume that your PC is connected to the
+Internet.
+
+=head1 PERL
+
+The official Perl for the Windows platform is available from
+ActiveState.
+
+  http://www.activestate.com
+  http://www.activestate.com/Products/ActivePerl/
+
+Registration is required, but it is free of charge.
+Follow the download and installation directions and you should end
+up with perl installed in the following directories under C:\Perl.
+
+  C:\Perl            # install directory for Perl
+  C:\Perl\bin        # programs directory (home of perl.exe)
+  C:\Perl\eg         # example code
+  C:\Perl\html       # html doc for the installed perl modules
+  C:\Perl\lib        # standard perl modules
+  C:\Perl\site\lib   # extram perl modules installed at this site
+
+=head1 OTHER PERL MODULES
+
+After you install the base Perl distribution, you need to install
+a number of other Perl modules, which would normally be downloaded
+from CPAN.  Because you are installing on a Windows platform, however,
+you will use ActiveState's Perl Package Manager (PPM, included with
+ActiveState Perl).  This installs Windows binary versions of many of the
+packages which are on CPAN from ActiveState's website.
+Take a look at this web page.
+
+  http://aspn.activestate.com/ASPN/Modules
+
+NOTE: The following instructions are good for the latest version of PPM (PPM3).
+Some syntax changed since PPM2.
+
+You can go into the PPM utility to manage installed binary distributions
+and check on which "repositories" of PPM files are currently configured.
+
+  C:\> ppm
+  PPM> repository
+  PPM> quit
+  C:\>
+
+Not all of the Perl modules you may want (i.e. mod_perl) are available from
+ActiveState, so you should know about a second popular repository for PPM 
+files.  Take a look at the following web pages.
+
+  http://theoryx5.uwinnipeg.ca/ppmpackages/
+  http://theoryx5.uwinnipeg.ca/
+
+To add this repository to the list for the ppm shell utility to
+search, do the following.
+
+  C:\> ppm
+  PPM> repository add theoryx5 http://theoryx5.uwinnipeg.ca/cgi-bin/ppmserver?urn:/PPMServer58
+  PPM> repository add officevision http://www.officevision.com/pub/ppm/           # for App::Options, App::Build, App::Context, etc.
+  PPM> quit
+  C:\>
+
+You may also want to add the following repositories if you don't find what you want
+on those other repositories.
+
+  PPM> repository add crazyinsomniac http://crazyinsomniac.perlmonk.org/perl/ppm/ # for various hard to find modules
+  PPM> repository add bribes http://www.bribes.org/perl/ppm/                      # for various hard to find modules
+  PPM> repository add gtk2 http://gtk2-perl.sourceforge.net/win32/ppm/            # for GTK2
+  PPM> repository add log4perl http://log4perl.sourceforge.net/ppm/               # for log4perl
+  PPM> repository add openi http://openinteract.sourceforge.net/ppmpackages/      # for Template Toolkit
+
+The following commands are to install some packages which are
+useful in order to develop or run applications based on the App-Context Framework.
+
+(Sometimes a module will fail to install because more than one version of it was found.
+You may need to follow up any such "install XYZ::ABC" module with a command like "install 1"
+which selects one of the versions found. Sometimes even this will fail, saying that the
+module is already installed.  In that case, you may need to type something like
+"install 1 -force -nofollow".  Sometimes you need to "search XYZ::ABC" before you do the
+"install 1 -force -nofollow".)
+
+  C:\> ppm
+  PPM> install TimeDate                # Date::Parse and Date::Format
+  PPM> install Module::Build
+  PPM> install App::Build
+  PPM> install App::Options
+  PPM> install XML::Simple
+  PPM> install XML::XPath
+  PPM> quit
+  C:\>
+
+=cut
+
+=head1 NMAKE
+
+The PPM method for installing software is described above.  However, the method of
+installing software which is most native to Perl is through the CPAN shell.
+In order for this to work, you need a "make" tool.  Microsoft provides "nmake" for
+this purpose.
+
+I found reference to "nmake" on Microsoft's site here.
+
+  http://support.microsoft.com/default.aspx?scid=kb;en-us;132084
+
+Then I downloaded the most recent version (a self-extracting archive) here.
+
+  http://download.microsoft.com/download/vc15/patch/1.52/w95/en-us/nmake15.exe
+
+After saving it on your disk, run the program to extract three files.
+
+  README.TXT
+  NMAKE.EXE
+  NMAKE.ERR
+
+Move these files to C:\Perl\bin.  This should put them in the PATH so that
+they will be found by the CPAN shell.
+
+=head1 MYSQL
+
+Install a Windows binary distribution of MySQL.
+Use a version of MySQL which is compatible with your Apache setup.
+
+  http://dev.mysql.com/downloads/
+  http://dev.mysql.com/doc/refman/5.0/en/windows-installation.html
+
+On March 13, 2006, the latest version of MySQL is 5.0.19.
+I download and install the "Windows Essentials (x86)" binary distribution.
+
+  http://dev.mysql.com/downloads/mysql/5.0.html
+
+Based on whatever password you entered in the configuration (instead of
+"xyzabc" shown below), enter something like the following in a new file
+named "C:\windows\my.cnf".
+
+  [client]
+  host            = localhost
+  port            = 3306
+  user            = root
+  password        = xyzabc
+  [mysql]
+  database        = test
+
+Then from the Windows command shell, you can type "mysql" and get
+in to the database directly.
+
+=head1 APACHE AND MOD_PERL: METHOD 1
+
+I recommend the all-in-one Apache/mod_perl/PHP/phpMyAdmin approach.
+
+  http://www.apachefriends.org/en/xampp-windows.html
+
+I downloaded the "XAMPP for Windows 1.5.1 [basic package]" Installer
+and the "XAMPP for Windows Add-Ons : Perl 5.8.7-2.2.0-pl2" Installer.
+
+=head1 APACHE AND MOD_PERL: METHOD 2
+
+You could download a binary distribution of Apache for Windows from apache.org.
+Then install mod_perl.
+
+  http://httpd.apache.org/docs/2.2/
+  http://httpd.apache.org/docs/2.2/platform/windows.html
+
+See the following sites for mod_perl.
+
+  http://perl.apache.org/
+  http://perl.apache.org/docs/2.0/os/win32/install.html
+
+After installing Perl and Apache, you can then install mod_perl
+via the PPM utility.
+
+  C:\> ppm
+  PPM> install mod_perl
+  PPM> quit
+  C:\>
+
+The mod_perl PPM package also includes the necessary Apache DLL
+mod_perl.so; a post-installation script should be run which will offer
+to copy this file to your Apache modules directory (eg, C:\Apache\modules).
+
+Note that the mod_perl package available from this site will always use
+the latest mod_perl sources compiled against the latest official Apache
+release; depending on changes made in Apache, you may or may not be able
+to use an earlier Apache binary. However, in the Apache Win32 world it
+is particularly a good idea to use the latest version, for bug and
+security fixes.
+
+=head1 CVS - CONCURRENT VERSION SYSTEM
+
+WinCVS
+TortoiseCVS ?
+
+=head1 SVN - SUBVERSION
+
+TortoiseSVN
+
+=head1 SVN - SUBVERSION SERVER
+
+NOTE: Setting up a Subversion server is not necessary for creating the typical
+Windows development/demonstration machine.
+
+If you have any Linux systems, you probably want to run the Subversion
+server software there.  However, if you really want to set up Subversion
+as a server on a Windows machine, here are some links I found.
+
+  http://blogs.vertigosoftware.com/teamsystem/archive/2006/01/16/Setting_up_a_Subversion_Server_under_Windows.aspx
+  http://excastle.com/blog/archive/2005/05/31/1048.aspx
+  http://svn1clicksetup.tigris.org/
+
+=cut
+

Added: p5ee/trunk/App-Context/lib/App/perlstyle.pod
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Context/lib/App/perlstyle.pod	Sun Sep  3 18:42:26 2006
@@ -0,0 +1,803 @@
+
+#############################################################################
+## $Id: perlstyle.pod,v 1.2 2002/11/01 20:18:22 spadkins Exp $
+#############################################################################
+
+=head1 NAME
+
+App::perlstyle - App::Context Perl Style Guide
+
+=head1 INTRODUCTION
+
+The following document describes some of the coding standards used in
+writing the App::Context framework (App-Options, App-Context, App-Repository,
+App-Widget, and other minor distributions).  This document exists for two
+purposes:
+
+=over
+
+=item 1. To provide a guideline for people who wish to contribute to or
+extend code in the App::Context framework.
+
+=item 2. To provide a samples style guide to any development group who
+desires a simple, effective coding standard for programming in Perl.
+
+=back
+
+Note that these are all guidelines, not unbreakable rules. 
+
+Note that with much of this document, it is not so much the Right Way as
+it is One Reasonable Way.  Everyone needs to have conventions in order to
+make life easier.
+
+=head1 CODING PRINCIPLES
+
+=head2 Perl Version
+
+The gold standard for backward compatibility is to support back to Perl
+5.5.3 (5.005_03).  When writing code, try to write it so that it will
+run on Perl 5.5.3.
+
+=head2 Documentation
+
+All modules will be documented using the POD examples in the module
+boilerplate.  The function, purpose, use of the module will be
+explained, and each public API will be documented with name,
+description, inputs, outputs, side effects, etc.
+
+If an array or hash reference is returned, document the size of the
+array (including what each element is, as appropriate) and name each key
+in the hash.  For complex data structures, map out the structure as
+appropriate.
+
+Also document what kind of data returned values are.  Is it an integer,
+a block of HTML, a boolean?
+
+All command-line program options will be documented using the
+boilerplate code for command-line programs.  Each available function,
+switch, etc. should be documented, along with a statement of function,
+purpose, use of the program.  Try not to use the same options as another
+program, for a different purpose.
+
+All web programs should be documented with a statement of function,
+purpose, and use in the comments of the program.
+
+Any external documents, and documentation for command-line programs and
+modules, should be written in POD, where appropriate. From there, they
+can be translated to many formats with the various pod2* translators. 
+Read the perlpod manpage before writing any POD, because although POD is
+not difficult, it is not what most people are used to.  It is not a
+regular markup language; it is just a way to make easy documentation
+for translating to other formats.  Read, and understand, the perlpod
+manpage, and ask us or someone else who knows if you have any questions.
+
+=head2 Version
+
+Use the boilerplate code for versions of modules, web programs, and
+command-line programs.  The $VERSION of the module will then reflect the
+CVS revision. 
+The Makefile.PL should contain the distribution version, independent
+of any individual file version within the CVS repository.
+
+Also, XS modules should probably have $VERSION
+also reflect the distribution, or else you'll need to recompile the
+shared library every time you make a change to the file, which is
+really a pain to do during development.
+
+Our distribution versions use tuples, where the first number is the
+major revision, the second number is the version, and third
+number is the subversion.  Odd-numbered versions are development
+versions.  Examples:
+
+    1.0.0       First release of App 1
+    1.0.1       Second release of App 1.0
+    1.0.10      etc.
+    1.1.0       First development release of App 1.2 (or 2.0)
+    2.0.0       First release of App 2
+
+Versions can be modified with a hyphen followed by some text, for
+special versions, or to give extra information.  Examples:
+
+    1.1.4-bender    Notes that this is a bender release
+    2.0.0-pre1      Notes that this is not final, but preview
+
+In perl 5.6.0, you can have versions like C<v2.0.0>, but this is not
+allowed in previous versions of perl.  So to convert a tuple version
+string to a string to use with $VERSION, use a regular integer for
+the revision, and three digits for version and subversion.  Examples:
+
+    1.1.6   ->      1.001006
+    2.0.0   ->      2.000000
+
+This way, perl can use the version strings in greater-than and
+less-than comparisons.
+
+
+=head2 Comments
+
+All code should be self-documenting as much as possible.  Only include
+necessary comments.  Use names like "$story_count", so you don't need to
+do something like:
+
+    # story count
+    my $sc = 0;
+
+Include any comments that are, or might be, necessary in order for
+someone else to understand the code.  Sometimes a simple one-line
+comment is good to explain what the purpose of the following code is
+for.  Sometimes each line needs to be commented because of a complex
+algorithm.  A good reference is Kernighan & Pike's
+I<Practice of Programming> about commenting.
+
+
+=head2 Warnings and Strict
+
+All code must compile and run cleanly with "use strict" enabled and the
+perl "-w" (warnings) option on.  If you must do something that -w or
+strict complains about, there are workarounds, but the chances that you
+really need to do it that way are remote.
+
+The one exception is the "Use of uninitialized variable" warnings.
+We have those disabled in App.pm, so by including "use
+App" you are disabling that warning in your code, too, and you don't
+need to worry about them.
+
+
+=head2 Lexical Variables
+
+Use only lexical variables, except for special global variables
+($VERSION, %ENV, @ISA, $!, etc.) or very special circumstances.
+Global variables
+for regular use are never appropriate.  When necessary, "declare"
+globals with "use vars", not with our() (our() was introduced in perl
+5.6).
+
+A lexical variable is created with my().  A global variable is
+pre-existing (if it is a special variable), or it pops into existence
+when it is used.  local() is used to tell perl to assign a temporary
+value to a variable.  This should only be used with special variables,
+like $/, or in special circumstances.  If you must assign to any global
+variable, consider whether or not you should use local().
+
+local() may also be used on elements of arrays and hashes, though there
+is seldom a need to do it, and you shouldn't.
+
+
+=head2 Exporting
+
+Do not export anything from a module by default. 
+Feel free to put anything you
+want to in @EXPORT_OK, so users of your modules can explicitly ask
+for symbols (e.g., "use App::Something qw(getFoo setFoo)"), but
+do not export them by default.
+
+
+=head2 Pass by Reference
+
+Arrays and hashes should be passed to and from functions by reference
+only.  Note that a list and an array are NOT the same thing.  This
+is perfectly fine:
+
+    return($user, $form, $constants);
+
+An exception might be a temporary array of discrete arguments:
+
+    my @return = ($user, $form);
+    push @return, $constants if $flag;
+    return @return;
+
+Although, usually, this is better (faster, easier to read, etc.):
+
+    if ($flag) {
+        return($user, $form, $constants);
+    } else {
+        return($user, $form);
+    }
+
+
+=head2 Garbage Collection
+
+Perl does pretty good garbage collection for you.  It will automatically
+clean up lexical variables that have gone out of scope and objects whose
+references have gone away.  Normally you don't need to worry about
+cleaning up after yourself, if using lexicals.
+
+However, some glue code, code compiled in C and linked to Perl, might
+not automatically clean up for you.  In such cases, clean up for
+yourself.  If there is a method in that glue to dispose or destruct,
+then use it as appropriate.
+
+Also, if you have a long-running function that has a large data
+structure in it, it is polite to free up the memory as soon as you are
+done with it, if possible.
+
+    my $huge_data_structure = get_huge_data_structure();
+    do_something_with($huge_data_structure);
+    undef $huge_data_structure;
+
+
+=head2 __END__ and __DATA__ and __PACKAGE__
+
+Do not use __END__ or __DATA__ in web programs.  They break mod_perl. 
+Also, __PACKAGE__ will likely not return the value you expect in web
+programs.  These are all fine for modules.
+
+
+=head2 Tests
+
+Modules should provide test code, with documentation on how to use
+it.
+
+
+=head2 STDIN/STDOUT
+
+Always report errors using the (yet-to-be-defined) App logging 
+facility.  Never print directly to STDERR. 
+Do not print directly to STDOUT, unless you need to
+print directly to the user's browser.
+
+In command-line programs, feel free to print to STDERR and STDOUT as
+needed.
+
+
+=head2 Files and Globs
+
+For constructing and parsing file paths, use File::Spec::Functions
+and File::Basename.  For creating or removing paths, use File::Path.
+This increases portability to non-Un*x platforms.
+
+    my $path = "$dir/$file";                # wrong
+    my $path = catfile($dir, $file);        # right
+
+    my $dir = ".";                          # wrong
+    my $dir = curdir();                     # right
+
+    mkdir("/path"), mkdir("/path/to"), ...  # wrong
+    `mkdir /path`; `mkdir /path/to`, ...    # very wrong
+    mkpath("/path/to/my/dir", 0, 0775);     # right
+
+Do not use the glob operator (C<glob('*')> or C<E<lt>*E<gt>>).  Use
+opendir() with readdir() instead.  Note that glob() is much more
+portable in perl 5.6 than it was in previous versions of perl, but
+its behavior is still unreliable, as each perl installation can
+choose to implement perl using local conventions instead of the
+default, which is via the File::Glob module.
+
+Do not use symbol table globs (not the same kind of glob as above!) like
+C<*foo> for anything, except for when direct symbol table manipulation
+is necessary, which it almost never is.
+
+
+=head2 System Calls
+
+Always check return values from system calls, including open(),
+close(), mkdir(), or anything else that talks directly to the system. 
+Perl built-in system calls return the error in $!; some functions in
+modules might return an error in $@ or some other way, so read the module's
+documentation if you don't know.  Always do something, even if it is
+just calling errorLog(), when the return value is not what you'd expect.
+
+
+=head1 STYLE
+
+Much of the style section is taken from the perlstyle manpage.  We make
+some changes to it here, but it wouldn't be a bad idea to read that
+document, too.
+
+=head2 Terminology
+
+=over 4
+
+=item App
+
+The name of the project is "App".
+There is no "App1" or "App2". 
+To specify a version, use "App 2.0" or "App 2.0.1".
+
+=item function vs. sub(routine) vs. method
+
+"Method" should be used only to refer to a subroutine that are object
+methods or class methods; that is, these are functions that are used
+with OOP that always take either an object or a class as the first
+argument. Regular subroutines, ones that are not object or class
+methods, are functions.  Class methods that create and return an object
+are optionally called constructors.
+
+=back
+
+
+=head2 Names
+
+Don't use single-character variables, except as iterator variables.
+
+Don't use two-character variables just to spite us over the above rule.
+
+Constants are in all caps; these are variables whose value will I<never>
+change during the course of the program.
+
+    $Minimum = 10;          # wrong
+    $MAXIMUM = 50;          # right
+
+Other variables are lowercase, with underscores separating the words. 
+They words used should, in general, form a noun (usually singular),
+unless the variable is a flag used to denote some action that should be
+taken, in which case they should be verbs (or gerunds, as appropriate)
+describing that action.
+
+    $thisVar      = 'foo';  # wrong
+    $this_var     = 'foo';  # right
+    $work_hard    = 1;      # right, verb, boolean flag
+    $running_fast = 0;      # right, gerund, boolean flag
+
+Arrays and hashes should be plural nouns, whether as regular arrays and
+hashes or array and hash references.  Do not name references with "ref"
+or the data type in the name.
+
+    @stories     = (1, 2, 3);      # right
+    $comment_ref = [4, 5, 6];      # wrong
+    $comments    = [4, 5, 6];      # right
+    $comment     = $comments->[0]; # right
+
+Make the name descriptive.  Don't use variables like "$sc" when you
+could call it "$story_count".  See L<"Comments">.
+
+Methods and Functions (except for special cases, like AUTOLOAD) begin
+with a verb, with words following to complete the action. 
+Multi-word names should be all lower-case, separated by underscores,
+in keeping with the "perlstyle" guide and most of the modules
+already on CPAN.  They
+should as clearly as possible describe the activity to be peformed, and
+the data to be returned.
+
+    $obj->getStory();             # wrong.
+    $obj->setStoryByName();       # wrong again.
+    $obj->getStoryByID();         # wrong again. This isn't Java!
+
+    $obj->get_story();            # right.
+    $obj->set_story_by_name();    # right.
+    $obj->get_story_by_id();      # right.
+
+Methods and Functions beginning with C<_> are special:
+they are not to be used
+outside the current file (i.e. "private"). 
+This is not enforced by the code itself,
+but by programmer convention only.
+
+For large for() loops, do not use $_, but name the variable.
+Do not use $_ (or assume it) except for when it is absolutely
+clear what is going on, or when it is required (such as with
+map() and grep()).
+
+    for (@list) {
+        print;              # OK; everyone knows this one
+        print uc;           # wrong; few people know this
+        print uc $_;        # better
+    }
+
+Note that the special variable C<_> I<should> be used when possible.
+It is a placeholder that can be passed to stat() and the file test
+operators, that saves perl a trip to re-stat the file.  In the
+example below, using C<$file> over for each file test, instead of
+C<_> for subsequent uses, is a performance hit.  You should be
+careful that the last-tested file is what you think it is, though.
+
+    if (-d $file) {         # $file is a directory
+        # ...
+    } elsif (-l _) {        # $file is a symlink
+        # ...
+    }
+
+Package names begin with a capital letter in each word, followed by
+lower case letters.
+
+    App::Standard          # good
+    App::Authz             # good
+    App::MainCode          # good
+
+Use all lower case for POD files which are documentation only.
+
+    App::styleguide        # good for doc only
+
+Naming for modules should be according to the following general rules.
+
+    All App services which have *broad* support from the 
+        [email protected] list would go into the "App" package
+    Naming style is similar to other modules on CPAN
+    Naming choice draws from precedent of other modules on CPAN
+    Naming choice draws from precedent of J2EE
+
+Packages which aren't intended to be instantiated as objects may
+have an "adjective" or "concept" for a name
+(i.e. App::Standard).  Packages which are
+Modules/Classes and are intended to be instantiated as objects
+should be nouns, potentially accompanied by modifying adjectives
+(i.e. App::Authen::Principal).
+
+=head2 Indents
+
+Code checked into CVS must never contain tabs.
+Patches of code with tabs do not email well, and different people
+have their tabstops set different ways.
+If you want to set tab stops on your editor, just make sure it
+converts tabs to spaces when it saves the file.
+
+Indentation for normal block-style coding should be 4 spaces. 
+The settings for Emacs and vim are as follows.
+
+=over
+
+=item * x?emacs: cperl-mode
+
+  .xemacs/custom.el:
+  ------------------
+  (custom-set-variables
+     '(cperl-indent-level 4)
+     '(cperl-continued-statement-offset 4)
+     '(cperl-tab-always-indent t)
+     '(indent-tabs-mode nil)
+  )
+
+=item * vim
+
+  .vimrc:
+  -------
+  set expandtab " replaces any tab keypress with the appropriate number of spaces
+  set tabstop=4 " sets tabs to 4 spaces
+
+=back
+
+=head2 Line Lengths
+
+Maximum line lengths should be 77 columns (or 75 columns for
+an unbroken line of characters).
+This is for maximum portability to different people's
+development environments and for decent transmission
+through e-mail to a wide array of e-mail clients
+(i.e. for patches).
+
+Example: Eudora 3.0.6 wraps a solid, single line of 80 non-whitespace
+characters (i.e. ######...#####) at character 76.  If there are
+spaces in the line, it allows lines up to character 78 before wrapping
+the last words down to the next line.  If sources have no more than
+77 characters in a line, a "diff -u" patch will add a column, and the
+lines will escape being folded.
+
+=head2 Blank Space
+
+No space before a semicolon that closes a statement.
+
+    foo(@bar) ;     # wrong
+    foo(@bar);      # right
+
+Line up corresponding items vertically.
+
+    my $foo   = 1;
+    my $bar   = 2;
+    my $xyzzy = 3;
+
+    open(FILE, $fh)   or die $!;
+    open(FILE2, $fh2) or die $!;
+
+    $rot13 =~ tr[abcedfghijklmnopqrstuvwxyz]
+                [nopqrstuvwxyzabcdefghijklm];
+
+    # note we use a-mn-z instead of a-z,
+    # for readability
+    $rot13 =~ tr[a-mn-z]
+                [n-za-m];
+
+Put blank lines where they make sense for readability, such as
+the following.
+Put blank lines between groups of code that do different things.  Put
+blank lines after your variable declarations.  Put a blank line before a
+final return() statement.  Put a blank line following a block (and
+before, with the exception of comment lines).
+
+An example:
+
+    # this is my function!
+    sub foo {
+        my (@data) = @_;
+        my $obj = new Constructor;
+        my ($var1, $var2);
+
+        $obj->setFoo($data[1]);
+        $var1 = $obj->getFoo(1);
+        $var2 = $obj->getFoo($var1);
+
+        display($var1, $var2);
+
+        return($data[0]);
+    }
+
+    print 1;
+
+
+=head2 Parentheses
+
+For control structures, there is a space between the keyword and opening
+parenthesis.  For functions, there is not.
+
+    for(@list)         # wrong
+    for (@list)        # right
+
+    my ($ref)          # OK
+    my ($ref)          # preferred
+
+    localtime ($time); # wrong
+    localtime($time);  # right
+
+Be careful about list vs. scalar context with parentheses!
+
+    my @array = ('a', 'b', 'c');
+    my ($first_element) = @array;           # a
+    my ($first_element) = ('a', 'b', 'c');  # a
+    my $element_count  = @array;            # 3
+    my $last_element   = ('a', 'b', 'c');   # c
+
+Always include parentheses after functions, even if there are no arguments.
+There are some exceptions, such as list operators (like print) and unary
+operators (like undef, delete, uc).
+
+There is no space inside the parentheses, unless it is needed for
+readability.
+
+    for ( map { [ $_, 1 ] } @list )     # OK
+    for ( @list )                       # not really OK, not horrible
+
+On multi-line expressions, match up the closing parenthesis with either
+the opening statement, or the opening parenthesis, whichever works best.
+Examples:
+
+    @list = qw(
+        bar
+        baz
+    );              # right
+
+    if ($foo && $bar && $baz
+         && $buz && $xyzzy
+    ) {
+        print $foo;
+    }
+
+Whether or not there is space following a closing parenthesis is
+dependent on what it is that follows.
+
+    print foo(@bar), baz(@buz) if $xyzzy;
+
+Note also that parentheses around single-statement control expressions,
+as in C<if $xyzzy>, are optional (and discouraged) C<if> it is I<absolutely>
+clear -- to a programmer -- what is going on.  There is absolutely no
+need for parentheses around C<$xyzzy> above, so leaving them out enhances
+readability.  Use your best discretion.  Better to include them, if
+there is any question.
+
+The same essentially goes for perl's built-in functions, when there is
+nothing confusing about what is going on (for example, there is only one
+function call in the statement, or the function call is separated by a
+flow control operator).  User-supplied functions must always include
+parentheses.
+
+    print 1, 2, 3;                          # good
+    delete $hash{key} if isAnon($uid);      # good
+
+
+However, if there is any possible confusion at all, then include the
+parentheses.  Remember the words of Larry Wall in the perlstyle manpage:
+
+    When in doubt, parenthesize.  At the very least it will
+    let some poor schmuck bounce on the % key in vi.
+
+    Even if you aren't in doubt, consider the mental welfare
+    of the person who has to maintain the code after you, and
+    who will probably put parens in the wrong place.
+
+So leave them out when it is absoutely clear to a programmer, but if
+there is any question, leave them in.
+
+
+=head2 Braces
+
+(This is about control braces, not hash/data structure braces.)
+
+There is always a space befor the opening brace.
+
+    while (<$fh>){      # wrong
+    while (<$fh>) {     # right
+
+A one-line block may be put on one line, and the semicolon may be
+omitted.
+
+    for (@list) { print }
+
+Otherwise, finish each statement with a semicolon, put the keyword and
+opening curly on the first line, and the ending curly lined up with the
+keyword at the end.
+
+    for (@list) {
+        print;
+        smell();
+    }
+
+perlstyle likes to have "uncuddled elses":
+
+    # right
+    if ($foo) {
+        print;
+    }
+    else {
+        die;
+    }
+
+    # wrong
+    if ($foo) {
+        print;
+    } else {
+        die;
+    }
+
+=head2 Operators
+
+Put space around most operators.  The primary exception is the for
+aesthetics; e.g., sometimes the space around "**" is ommitted,
+and there is never a space before a ",", but always after.
+
+    print $x , $y;  # wrong
+    print $x, $y;   # right
+
+    $x = 2 >> 1;    # good
+    $y = 2**2;      # ok
+
+Note that "&&" and "||" have a higher precedence than "and" and "or". 
+Other than that, they are exactly the same.  It is best to use the lower
+precedence version for control, and the higher for testing/returning
+values.  Examples:
+
+    $bool = $flag1 or $flag2;       # WRONG (doesn't work)
+    $value = $foo || $bar;          # right
+    open(FILE, $file) or die $!;
+
+    $true  = foo($bar) && baz($buz);
+    foo($bar) and baz($buz);
+
+Note that "and" is seldom ever used, because the statement above is
+better written using "if":
+
+    baz($buz) if foo($bar);
+
+Most of the time, the confusion between and/&&, or/|| can be alleviated
+by using parentheses.  If you want to leave off the parentheses then you
+I<must> use the proper operator.  But if you use parentheses -- and
+normally, you should, if there is any question at all -- then it doesn't
+matter which you use.  Use whichever is most readable and aesthetically
+pleasing to you at the time, and be consistent within your block of code.
+
+Break long lines AFTER operators, except for "and", "or", "&&", "||".
+Try to keep the two parts to a binary operator (an operator that
+has two operands) together when possible.
+
+    print "foo" . "bar" . "baz"
+        . "buz";                    # wrong
+
+    print "foo" . "bar" . "baz" .
+        "buz";                      # right
+
+    print $foo unless $x == 3 && $y ==
+        4 && $z == 5;               # wrong
+
+    print $foo unless $x == 3 && $y == 4
+        && $z == 5;                 # right
+
+
+=head2 Other
+
+Put space around a complex subscript inside the brackets or braces.
+
+    $foo{$bar{baz}{buz}};       # OK
+    $foo{ $bar{baz}{buz} };     # better
+
+In general, use single-quotes around literals, and double-quotes
+when the text needs to be interpolated. 
+
+It is OK to omit quotes around names in braces and when using
+the => operator, but be careful not to use a name that doubles as
+a function; in that case, quote.
+
+    $what{'time'}{it}{is} = time();
+
+When making compound statements, put the primary action first.
+
+    open(FILE, $fh) or die $!;      # right
+    die $! unless open(FILE, $fh);  # wrong
+
+    print "Starting\n" if $verbose; # right
+    $verbose && print "Starting\n"; # wrong
+
+
+Use here-docs instead of repeated print statements.
+
+        print <<EOT;
+    This is a whole bunch of text.
+    I like it.  I don't need to worry about messing
+    with lots of print statements and lining them up.
+    EOT
+
+Just remember that unless you put single quotes around your here-doc
+token (<<'EOT'), the text will be interpolated, so escape any "$" or "@"
+as needed.
+
+
+
+=head1 REQUIREMENTS RFC AND CODING PROCEDURE
+
+This is for new programs, modules, specific APIs, or anything else.
+
+Contact for core team is the App-development mailing list.
+Discuss all ideas there.
+
+The basic process for a new App service is:
+
+    get the blessing from the App list for a top-level package name
+    (i.e. "App::NewModule")
+    begin a CPAN-able source directory skeleton
+    write the spec (no code) as POD inside the target module(s)
+    publish HTML to the web
+    announce whenever progress is made so that comments can be sought
+    code is added after there is broad support for the API spec
+    and supporting doc
+
+
+=head1 BUG REPORTS, PATCHES, CVS
+
+We don't have bug tracking set up yet.
+
+Use C<diff -u> for patches.
+
+Do not add anything to the main branches in CVS without approval from
+a member of the core team.
+
+
+=head1 TO DO
+
+lots
+
+=head1 ACKNOWLEDGEMENTS
+
+This style guide was based on the slashcode style guide.
+It is in conformance with the general Perl style guide
+(perldoc perlstyle) and the mod_perl style guide.
+
+  http://slashcode.com/docs/slashstyle.html
+  http://search.cpan.org/author/JHI/perl/pod/perlstyle.pod
+  http://perl.apache.org/docs/2.0/devel/modperl_style/modperl_style.html
+
+It is also in the spirit of the C-language Apache style guide.
+
+  http://httpd.apache.org/dev/styleguide.html
+
+
+=head1 CHANGES
+
+    $Log: perlstyle.pod,v $
+    Revision 1.2  2002/11/01 20:18:22  spadkins
+    convert from P5EEx::Blue to App::Context
+
+    Revision 1.1  2002/09/09 01:34:10  spadkins
+    first import
+
+    Revision 1.2  2001/11/30 16:00:52  spadkins
+    Renamed 'Component' to 'Service' throughout. Improved perldocs.
+
+    Revision 1.1  2001/11/22 05:16:59  spadkins
+    Major new architectural framework proposal
+
+    Revision 1.1  2001/11/16 23:21:38  spadkins
+    initial stuff
+
+
+
+=head1 VERSION
+
+$Id: perlstyle.pod,v 1.2 2002/11/01 20:18:22 spadkins Exp $
+
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.