App-Context

 view release on metacpan or  search on metacpan

lib/App.pm  view on Meta::CPAN

The first AOP
feature planned is the printing of arguments on entry to a method and
the printing of arguments and return values on exit of a a method.

This is useful
for debugging and the generation of object-message traces to validate
or document the flow of messages through the system.

Detailed Conditions:

  * use(001) class does not exist: throw a App::Exception
  * use(002) class never used before: should succeed
  * use(003) class used before: should succeed
  * use(004) can use class after: should succeed

=cut

my (%used);

sub use {
    &App::sub_entry if ($App::trace);

lib/App.pm  view on Meta::CPAN

        # local (*VERSION) = ${*{"$class\::"}}{VERSION};
        # print "$class VERSION: ", ${*VERSION{SCALAR}}, "\n";

        # but I decided to look for *any* symbol table entry instead.
        if (%{*{"$class\::"}}) {  # if any symbols exist in the symbol table
            # do nothing
        }
        elsif ($class =~ /^([A-Za-z0-9_:]+)$/) {
            eval "use $1;";
            if ($@) {
                App::Exception->throw(
                    error => "class $class failed to load: $@\n",
                );
            }
        }
        else {
            App::Exception->throw(
                error => "Tried to load class [$class] with illegal characters\n",
            );
        }
    }
    &App::sub_exit() if ($App::trace);
}

# $dir = App->mkdir($prefix, "data", "app", "Context");
sub mkdir {
    &App::sub_entry if ($App::trace);

lib/App/Conf/File.pm  view on Meta::CPAN

    $conf_file = $options->{conf_file};
    if (defined $conf_file) {
        if ($conf_file) {
            @conf_file = ( $conf_file );
            $conf_type = "pl";
            if ($conf_file =~ /\.([^\.]+)$/) {
                $conf_type = $1;
            }
            # if a config file is specified, it must exist
            if (! -r $conf_file) {
                App::Exception::Conf->throw(
                    error => "create(): [$conf_file] $!\n"
                );
            }
        }
    }
    else {
        #################################################################
        # 3. find the directory the program was run from
        #    we will use this directory to search for the
        #    initialization configuration file.

lib/App/Conf/File.pm  view on Meta::CPAN

                    $serializer_class = "App::Serializer::$serializer";
                }
                else {
                    $serializer_class = "App::Serializer";
                }
            }

            if ($serializer_class) {
                eval "use $serializer_class;";
                if ($@) {
                    App::Exception::Conf->throw(
                        error => "create(): error loading $serializer_class serializer class: $@\n"
                    );
                }
                $conf = $serializer_class->deserialize($text);
                if (! %$conf) {
                    App::Exception::Conf->throw(
                        error => "create(): $serializer_class produced empty config\n"
                    );
                }
            }
            else { # don't bother with a serializer
                $conf = {};
                if ($text =~ /^[ \t\n]*\$[a-zA-Z][a-zA-Z0-9_]* *= *(\{.*\};[ \n]*)$/s) {
                    $text = "\$conf = $1";   # untainted now
                    eval($text);
                    if ($@) {
                        App::Exception::Conf->throw(
                            error => "create(): [$conf_file] error eval'ing config text: $@\n"
                        );
                    }
                }
                else {
                    App::Exception::Conf->throw(
                        error => "create(): [$conf_file] config text doesn't match '\$var = {...};'\n"
                    );
                }
            }
        }
    }
    
    if ($options->{conf} && ref($options->{conf}) eq "HASH") {
        App::Reference->overlay($conf, $options->{conf});
    }

lib/App/Context.pm  view on Meta::CPAN

        if ($App::DEBUG && $self->dbg(3));
    my $options = $self->{options};

    my ($args, $new_service, $override, $lightweight, $attrib);
    my ($service, $conf, $class, $session);
    my ($service_store, $service_conf, $service_type, $service_type_conf);
    my ($default);

    # $type (i.e. SessionObject, Session, etc.) must be supplied
    if (!defined $type) {
        App::Exception->throw(
            error => "cannot create a service of unknown type\n",
        );
    }

    if (%named) {
        $args = \%named;
    }
    else {
        $args = {};
    }

lib/App/Context.pm  view on Meta::CPAN

sub get_current_events {
    &App::sub_entry if ($App::trace);
    my ($self, $events, $time) = @_;
    $time = time() if (!$time);
    my $time_of_next_event = 0;
    @$events = ();
    my $scheduled_event  = $self->{scheduled_event};
    my $scheduled_events = $self->{scheduled_events};
    my $verbose          = $self->{verbose};
    my ($event);
    # note: go in reverse order so that the splice() doesn't throw our indexes off
    # we do unshift() to keep events executing in FIFO order for a particular time
    for (my $i = $#$scheduled_events; $i >= 0; $i--) {
        $event = $scheduled_events->[$i];
        $self->log({level=>5},"Checking event: time=$time [$event->{time}, every $event->{interval}] $event->{method}().\n");
        if ($event->{time} <= $time) {
            unshift(@$events, $event);
            if ($event->{time} && $event->{interval}) {
                $event->{time} += $event->{interval}; # reschedule the event
                $self->log({level=>5},"Event Rescheduled: time=$time [$event->{time}, every $event->{interval}] $event->{method}().\n");
                if ($time_of_next_event == 0 || $event->{time} < $time_of_next_event) {

lib/App/Exceptions.pm  view on Meta::CPAN

Stacktrace generation is turned on for all the exception classes.

See Exception::Class on CPAN for more information on
how this is done.

Note that there is really only one general
exception class defined for each App-Context Service. 
Within each Service, there may be a separate
exception hierarchy which is more fine-grained.  However, each
service is responsible to (1) handle these exceptions,
(2) handle these exceptions and rethrow
the general exception defined for the service, or
(3) derive all of the exceptions from the general exception.

=head1 EXCEPTION CLASSES

=over

=item * App::Exception

This is the base class for all exceptions generated within App (all

lib/App/Reference.pm  view on Meta::CPAN

    Sample Usage:

=cut

sub create {
    my $self = shift;
    print "create(@_)\n" if ($App::DEBUG);
    return {} if ($#_ == -1);
    if (ref($_[0]) ne "") {
        return $_[0] if ($#_ == 0);
        App::Exception->throw(error => "Reference->create(): args supplied with an ARRAY ref\n")
            if (ref($_[0]) eq "ARRAY");
        my ($ref, $i);
        $ref = shift;
        for ($i = 0; $i < $#_; $i += 2) {
            #print "arg: $_[$i] => $_[$i+1]\n";
            $ref->{$_[$i]} = $_[$i+1];
        }
        return $ref;
    }
    if ($_[0] eq "array") {
        shift;
        return [ @_ ];
    }
    elsif ($#_ % 2 == 0) {
        App::Exception->throw(error => "Reference->create(): Odd number of named parameters\n");
    }
    return { @_ };
}

#############################################################################
# _init()
#############################################################################

=head2 _init()

lib/App/Serializer.pm  view on Meta::CPAN

            $serializer_class = "App::Serializer::XML";
        }
        elsif ($serialized_data =~ /^</) {
            $serializer_class = "App::Serializer::XMLSimple";
        }
    }

    if ($serializer_class) {
        eval "use $serializer_class;";
        if ($@) {
            App::Exception::Serializer->throw(
                error => "create(): error loading $serializer_class serializer class\n"
            );
        }
        $data = $serializer_class->deserialize($serialized_data);
    }
    else {
        if ($serialized_data =~ /^\$[a-zA-Z][a-zA-Z0-9_]* *= *(.*)$/s) {
            $serialized_data = "\$data = $1";   # untainted now
            eval($serialized_data);
            die "Deserialization Error: $@" if ($@);

lib/App/devguide.pod  view on Meta::CPAN


   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

lib/App/exceptions.pod  view on Meta::CPAN


  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

lib/App/exceptions.pod  view on Meta::CPAN

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

lib/App/exceptions.pod  view on Meta::CPAN

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 ($@) {

lib/App/exceptions.pod  view on Meta::CPAN


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")

lib/App/exceptions.pod  view on Meta::CPAN

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



( run in 0.345 second using v1.01-cache-2.11-cpan-496ff517765 )