cvsuser     03/12/03 08:14:46

  Modified:    App-Context/lib App.pm
  Log:
  convert to use App::Options
  
  Revision  Changes    Path
  1.7       +94 -235   p5ee/App-Context/lib/App.pm
  
  Index: App.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Context/lib/App.pm,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -w -r1.6 -r1.7
  --- App.pm    19 May 2003 17:41:11 -0000      1.6
  +++ App.pm    3 Dec 2003 16:14:46 -0000       1.7
  @@ -1,6 +1,6 @@
   
   #############################################################################
  -## $Id: App.pm,v 1.6 2003/05/19 17:41:11 spadkins Exp $
  +## $Id: App.pm,v 1.7 2003/12/03 16:14:46 spadkins Exp $
   #############################################################################
   
   package App;
  @@ -250,14 +250,14 @@
   
    * Global Variable: $App::DEBUG      integer
    * Global Variable: $App::DEBUGFILE  file for debug output
  - * Global Variable: $App::dbgscope   scope for debug output
  + * Global Variable: %App::dbgscope   scope for debug output
   
   =cut
   
   if (!defined $App::DEBUG) {
       $App::DEBUG = 0;
       $App::DEBUGFILE = "";
  -    $App::dbgscope = ();
  +    %App::dbgscope = ();
   }
   
   #################################################################
  @@ -271,7 +271,7 @@
   #    -debug=6,App::Repository::DBI.select_rows   (indiv. methods)
   {
       my ($debug, $pkg);
  -    $debug = $App::conf{debug};
  +    $debug = $App::options{debug};
       if (defined $debug && $debug ne "") {
           if ($debug =~ s/^([0-9]+),?//) {
               $App::DEBUG = $1;
  @@ -283,7 +283,7 @@
           }
       }
   
  -    my $debugfile = $App::conf{debugfile};
  +    my $debugfile = $App::options{debugfile};
       if ($debugfile) {
           if ($debugfile !~ /^[>|]/) {
               $debugfile = ">> $debugfile";
  @@ -292,7 +292,7 @@
       }
   
       $App::trace_subs = 0;
  -    if ($App::conf{trace}) {
  +    if ($App::options{trace}) {
           $App::trace_subs = 1;
       }
   }
  @@ -434,7 +434,7 @@
   =head2 new()
   
   The App->new() method is not a constructor for
  -a App class.  However, it is a constructor, returning
  +an App class.  Rather, it is a Factory-style constructor, returning
   an object of the class given as the first parameter.
   
   If no parameters are given,
  @@ -454,7 +454,7 @@
       Sample Usage: 
   
       $context = App->new();
  -    $dbh = App->new("DBI", "new", "dbi:mysql:db", "dbuser", "dbpasswd2");
  +    $dbh = App->new("DBI", "new", "dbi:mysql:db", "dbuser", "xyzzy");
       $cgi = App->new("CGI", "new");
   
   =cut
  @@ -492,9 +492,14 @@
   
   =head2 context()
   
  -    * Signature: $context = App->context()
  +    * Signature: $context = App->context();      # most common, used in "app"
  +    * Signature: $context = App->context(%named);                 # also used
  +    * Signature: $context = App->context($named, %named);         # variation
  +    * Signature: $context = App->context($name, %named);               # rare
  +    * Signature: $context = App->context($named, $name, %named);       # rare
       * Param:     context_class class  [in]
  -    * Param:     conf_file     string [in]
  +    * Param:     config_file     string [in]
  +    * Param:     prefix          string [in]
       * Return:    $context     App::Context
       * Throws:    App::Exception::Context
       * Since:     0.01
  @@ -504,7 +509,7 @@
       $context = App->context();
       $context = App->context(
           context_class => "App::Context::HTTP",
  -        conf_file => "app.xml",
  +        config_file => "app.xml",
       );
   
   This static (class) method returns the $context object
  @@ -523,6 +528,19 @@
   configured at deployment-time, and the proper physical class
   is instantiated at run-time.
   
  +The new() method of the configured Context class is called to
  +instantiate the proper Context object.  The $named args are
  +combined with the %named args and passed as a single hash
  +reference to the new() method.
  +
  +Environment variables:
  +
  +    PREFIX - set the $conf->{prefix} variable if not set to set app root dir
  +    APP_CONTEXT_CLASS - set the Perl module to instantiate for the Context
  +    GATEWAY_INTERFACE - assume mod_perl, use App::Context::ModPerl
  +    HTTP_USER_AGENT - assume CGI, use App::Context::HTTP
  +      (otherwise, use App::Context::Cmd, assuming it is from command line)
  +
   =cut
   
   my (%context);  # usually a singleton per process (under "default" name)
  @@ -532,63 +550,66 @@
       &App::sub_entry if ($App::trace_subs);
       my $self = shift;
   
  -    my ($name, $args, $i);
  -    if ($#_ == -1) {
  -        $args = (%App::conf) ? \%App::conf : {};
  -        $name = "default";
  +    my ($name, $conf, $i);
  +    if ($#_ == -1) {                  # if no conf supplied (the normal case)
  +        $conf = (%App::options) ? \%App::options : {};         # refer to conf hash
  +        $name = "default";                 # name of the singleton is default
       }
  -    else {
  -        if (ref($_[0]) eq "HASH") {
  -            $args = shift;
  -            $name = shift if ($#_ % 2 == 0);
  -            for ($i = 0; $i < $#_; $i++) {
  -                $args->{$_[$i]} = $_[$i+1];
  +    else {                                     # named args were supplied ...
  +        if (ref($_[0]) eq "HASH") {                 # ... as a hash reference
  +            $conf = shift;                   # note that a copy is *not* made
  +            $name = shift if ($#_ % 2 == 0);   # get name if it exists (odd#)
  +            for ($i = 0; $i < $#_; $i++) {            # copy other named args
  +                $conf->{$_[$i]} = $_[$i+1];              # into the conf hash
               }
           }
  -        else {
  -            $name = shift if ($#_ % 2 == 0);
  -            $args = ($#_ > -1) ? { @_ } : {};
  +        else {                                  # ... as a list of var/values
  +            $name = shift if ($#_ % 2 == 0);    # if odd #, first is the name
  +            $conf = ($#_ > -1) ? { @_ } : {};   # the rest are named args
           }
  -        $name = $args->{name} if (!$name);
  -        $name = "default" if (!$name);
  +        $name = $conf->{name} if (!$name);  # if name not given, look in conf
  +        $name = "default" if (!$name);                # use "default" as name
       }
  -    return ($context{$name}) if (defined $context{$name});
  +    return ($context{$name}) if (defined $context{$name});   # return context
       
  -    if (! $args->{context_class}) {
  +    if (! $conf->{context_class}) {
           if (defined $ENV{APP_CONTEXT_CLASS}) {     # env variable set?
  -            $args->{context_class} = $ENV{APP_CONTEXT_CLASS};
  +            $conf->{context_class} = $ENV{APP_CONTEXT_CLASS};
           }
           else {   # try autodetection ...
               my $gateway = $ENV{GATEWAY_INTERFACE};
               if (defined $gateway && $gateway =~ /CGI-Perl/) {  # mod_perl?
  -                $args->{context_class} = "App::Context::ModPerl";
  +                $conf->{context_class} = "App::Context::ModPerl";
               }
               elsif ($ENV{HTTP_USER_AGENT}) {  # running as CGI script?
  -                $args->{context_class} = "App::Context::HTTP";
  +                $conf->{context_class} = "App::Context::HTTP";
               }
  -            # let's be real... these next two are not critical right now
  -            #elsif ($ENV{DISPLAY}) { # running with an X DISPLAY var set?
  -            #    $args->{context_class} = "App::Context::Gtk";
  -            #}
  -            #elsif ($ENV{TERM}) { # running with a TERM var for Curses?
  -            #    $args->{context_class} = "App::Context::Curses";
  -            #}
  -            else {   # fall back to CGI, because it works OK in command mode
  -                $args->{context_class} = "App::Context::Cmd";
  +            else {   # assume it is from the command line
  +                $conf->{context_class} = "App::Context::Cmd";
               }
           }
       }
  -    if (!$args->{prefix}) {
  -        if ($ENV{PREFIX}) {
  -            $args->{prefix} = $ENV{PREFIX};
  +    if (!$conf->{prefix}) {                       # if this isn't already set
  +        if ($ENV{PREFIX}) {                 # but it's set in the environment
  +            $conf->{prefix} = $ENV{PREFIX};                     # then set it
           }
       }
   
  -    $context{$name} = $self->new($args->{context_class}, "new", $args);
  +    # instantiate Context and cache it (it's reference) for future use
  +    $context{$name} = $self->new($conf->{context_class}, "new", $conf);
  +
       &App::sub_exit($context{$name}) if ($App::trace_subs);
       return($context{$name});
   }
   
  +sub reset {
  +    &App::sub_entry if ($App::trace_subs);
  +    my ($self, $name) = @_;
  +    $name = "default" if (!defined $name);
  +    delete $context{$name};
  +    &App::sub_exit() if ($App::trace_subs);
  +}
  +
   #############################################################################
   # conf()
   #############################################################################
  @@ -597,39 +618,27 @@
   
       * Signature: $conf = App->conf(%named);
       * Param:     conf_class  class  [in]
  -    * Param:     conf_file   string [in]
  +    * Param:     config_file string [in]
       * Return:    $conf      App::Conf
       * Throws:    App::Exception::Conf
       * Since:     0.01
   
  +This gets the Conf object from the Context.
  +
  +If args are passed in, they are only effective in affecting the Context
  +if the Context has not been instantiated before.
  +
  +After the Context is instantiated by either the App->context() call or the
  +App->conf() call, then subsequent calls to either method may or may not
  +include arguments.  It will not have any further effect because the
  +Context object instantiated earlier will be used.
  +
   =cut
   
   sub conf {
       &App::sub_entry if ($App::trace_subs);
       my $self = shift;
  -
  -    my ($name, $args, $i);
  -    if ($#_ == -1) {
  -        $args = {};
  -        $name = "default";
  -    }
  -    else {
  -        if (ref($_[0]) eq "HASH") {
  -            $args = shift;
  -            $name = shift if ($#_ % 2 == 0);
  -            for ($i = 0; $i < $#_; $i += 2) {
  -                $args->{$_[$i]} = $_[$i+1];
  -            }
  -        }
  -        else {
  -            $name = shift if ($#_ % 2 == 0);
  -            $args = ($#_ > -1) ? { @_ } : {};
  -        }
  -        $name = $args->{name} if (!$name);
  -        $name = "default" if (!$name);
  -    }
  -
  -    my $retval = $self->context($args)->conf();
  +    my $retval = $self->context(@_)->conf();
       &App::sub_exit($retval) if ($App::trace_subs);
   }
   
  @@ -645,6 +654,8 @@
       * Throws:    App::Exception
       * Since:     0.01
   
  +Gets version info about the framework.
  +
   =cut
   
   sub info {
  @@ -658,6 +669,11 @@
   #############################################################################
   # Aspect-oriented programming support
   #############################################################################
  +# NOTE: This can be done much more elegantly at the Perl language level,
  +# but it requires version-specific code.  I created these subroutines so that
  +# any method that is instrumented with them will enable aspect-oriented
  +# programming in Perl versions from 5.5.3 to the present.
  +#############################################################################
   
   my $calldepth = 0;
   
  @@ -674,6 +690,9 @@
       * Throws:    none
       * Since:     0.01
   
  +This is called at the beginning of a subroutine or method (even before $self
  +may be shifted off).
  +
   =cut
   
   sub sub_entry {
  @@ -769,6 +788,7 @@
       * Throws:    none
       * Since:     0.01
   
  +This subroutine is called just before you return from a subroutine or method.
   =cut
   
   sub sub_exit {
  @@ -811,167 +831,6 @@
       }
       return(@_);
   }
  -
  -##############################################################################
  -## dbg()
  -##############################################################################
  -#
  -#=head2 dbg()
  -#
  -#The dbg() method is used to check whether a given line of debug output
  -#should be generated.  
  -#It returns true or false (1 or 0).
  -#
  -#If all three parameters are specified, this function
  -#returns true only when the global debug level ($App::Context::DEBUG)
  -#is at least equal to $level and when the debug scope
  -#is set to debug this class and method.
  -#
  -#    * Signature: $flag = $context->dbg($class,$method,$level);
  -#    * Param:     $class       class   [in]
  -#    * Param:     $method      string  [in]
  -#    * Param:     $level       integer [in]
  -#    * Return:    void
  -#    * Throws:    App::Exception::Context
  -#    * Since:     0.01
  -#
  -#    Sample Usage: 
  -#
  -#    $context->dbgprint("this is debug output")
  -#        if ($App::DEBUG && $context->dbg(3));
  -#
  -#    $context->dbgprint("this is debug output")
  -#        if ($context->dbg(3));
  -#
  -#The first usage is functionally identical to the second, but the check
  -#of the global debug level explicitly reduces the runtime overhead to
  -#eliminate any method calls when debugging is not turned on.
  -#
  -#=cut
  -#
  -#my %debugscope;
  -#
  -#sub dbg {
  -#    my ($self, $level) = @_;
  -#    return 0 if (! $App::DEBUG);
  -#    $level = 1 if (!defined $level);
  -#    return 0 if (defined $level && $App::DEBUG < $level);
  -#    my ($debugscope, $stacklevel);
  -#    my ($calling_package, $file, $line, $subroutine, $hasargs, $wantarray);
  -#    $debugscope = (ref($self) eq "") ? \%debugscope : $self->{debugscope};
  -#    $stacklevel = 1;
  -#    ($calling_package, $file, $line, $subroutine, $hasargs, $wantarray) = 
caller($stacklevel);
  -#    while (defined $subroutine && $subroutine eq "(eval)") {
  -#        $stacklevel++;
  -#        ($calling_package, $file, $line, $subroutine, $hasargs, $wantarray) = 
caller($stacklevel);
  -#    }
  -#    return 1 if (! defined $debugscope);
  -#    return 1 if (! %$debugscope);
  -#    return 1 if (defined $debugscope->{$calling_package});
  -#    return 1 if (defined $debugscope->{$subroutine});
  -#    return 0;
  -#}
  -#
  -##############################################################################
  -## dbgprint()
  -##############################################################################
  -#
  -#=head2 dbgprint()
  -#
  -#The dbgprint() method is used to produce debug output.
  -#The output goes to an output stream which is appropriate for
  -#the runtime context in which it is called.
  -#
  -#    * Signature: $flag = $context->dbgprint(@args);
  -#    * Param:     @args        string  [in]
  -#    * Return:    void
  -#    * Throws:    App::Exception::Context
  -#    * Since:     0.01
  -#
  -#    Sample Usage: 
  -#
  -#    $context->dbgprint("this is debug output")
  -#        if ($App::DEBUG && $context->dbg(3));
  -#
  -#=cut
  -#
  -#sub dbgprint {
  -#    my $self = shift;
  -#    if (defined $App::conf{debugfile}) {
  -#        print App::DEBUGFILE $$, ": ", @_, "\n";
  -#    }
  -#    else {
  -#        print STDERR "Debug: ", @_, "\n";
  -#    }
  -#}
  -#
  -##############################################################################
  -## dbglevel()
  -##############################################################################
  -#
  -#=head2 dbglevel()
  -#
  -#The dbglevel() method is used to set the debug level.
  -#Setting the dbglevel to 0 turns off debugging output and is suitable
  -#for production use.  Setting the dbglevel to 1 or higher turns on
  -#increasingly verbose debug output.
  -#
  -#    * Signature: $context->dbglevel($dbglevel);
  -#    * Signature: $dbglevel = $context->dbglevel();
  -#    * Param:     $dbglevel   integer
  -#    * Return:    $dbglevel   integer
  -#    * Throws:    App::Exception::Context
  -#    * Since:     0.01
  -#
  -#    Sample Usage: 
  -#
  -#    $context->dbglevel(1);             # turn it on
  -#    $context->dbglevel(0);             # turn it off
  -#    $dbglevel = $context->dbglevel();  # get the debug level
  -#
  -#=cut
  -#
  -#sub dbglevel {
  -#    my ($self, $dbglevel) = @_;
  -#    $App::DEBUG = $dbglevel if (defined $dbglevel);
  -#    return $App::DEBUG;
  -#}
  -#
  -##############################################################################
  -## dbgscope()
  -##############################################################################
  -#
  -#=head2 dbgscope()
  -#
  -#The dbgscope() method is used to get the hash which determines which
  -#debug statements are to be printed out when the debug level is set to a
  -#positive number.  It returns a hash reference.  If class names or
  -#"class.method" names are defined in the hash, it will cause the
  -#debug statements from those classes or methods to be printed.
  -#
  -#    * Signature: $dbgscope = $context->dbgscope();
  -#    * Param:     void
  -#    * Return:    $dbgscope   {}
  -#    * Throws:    App::Exception::Context
  -#    * Since:     0.01
  -#
  -#    Sample Usage: 
  -#
  -#    $dbgscope = $context->dbgscope();
  -#    $dbgscope->{"App::Context::CGI"} = 1;
  -#    $dbgscope->{"App::Context::CGI.process_request"} = 1;
  -#
  -#=cut
  -#
  -#sub dbgscope {
  -#    my $self = shift;
  -#    my $dbgscope = $self->{dbgscope};
  -#    if (!defined $dbgscope) {
  -#        $dbgscope = {};
  -#        $self->{dbgscope} = $dbgscope;
  -#    }
  -#    $dbgscope;
  -#}
   
   =head1 ACKNOWLEDGEMENTS
   
  
  
  

Reply via email to