App-Modular

 view release on metacpan or  search on metacpan

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

#!/usr/bin/perl -w
#----------------------------------------------------------------------------
#   App::Modular - perl program modularization framewok
#   App::Modular.pm: module management class
#
#   Copyright (c) 2003-2004 Baltasar Cevc
#
#   This code is released under the L<perlartistic> Perl Artistic
#   License, which can should be accessible via the C<perldoc
#   perlartistic> command and the file COPYING provided with this
#
#   DISCLAIMER: THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND
#   COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
#   IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY
#   OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE
#   OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
#   TRADEMARKS OR OTHER RIGHTS.
#   IF YOU USE THIS SOFTWARE, YOU DO SO AT YOUR OWN RISK.
#
#   See this internet site for more details: http://technik.juz-kirchheim.de/
#
#   Creation:       02.12.03    bc
#   Last Update:    06.04.08    bc
#   Version:         0. 1. 3  
# ----------------------------------------------------------------------------

##################################
##        PRAGMA/DEPS           ##
##################################
use strict;
use warnings;
use 5.006_001;

package App::Modular;
use Carp;
use base qw(Class::Singleton);

##################################
##           VERSION            ##
##################################
our ($VERSION);
$VERSION = 0.001_003;

##################################
##           METHODS            ##
##################################
### new_instance
# only one instance of App::Modular should exist in a running program,
# so we use singleton
# => this is our "new" function which initializes the variables
#    however, the program should only use "..=instance App::Modular;"
#    to get the object, Class::Singleton will initialize everything
#    when and only if needed
sub _new_instance {
   my ($type) = @_;
   my $self  = bless { }, $type;

   $self->{'modules'} = {};             # hash modulename => object
   $self->{'modules_files'} = {};;      # hash modulename => source file
   $self->{'dependencies'} = {};;       # hast modulename => /-separated list
                                        # of modules the module depends on
   $self->{'debuglevel'} = 1;           # (default) verbose level
   $self->{'debugtrace'} = 0;           # print stack trace with debug output

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

   # it, otherwise we fail *return undef)
      if ($self->{'autoload'}) {
         if ($noautoload) {
         # autoloading is enabled -> check if we can load
            $self->mlog(5, "module autoload temporarily disabled");
            return undef;
         } else {
            $self->mlog(20, "autoloading module $module_name");
            $self->module_register($module_name);
            if ($self->module_isloaded($module_name)) { 
               return $self->module($module_name);
            } else {
               $self->mlog(0, "ERROR: autoload of module $module_name ".
                              "failed.");
               return undef;
            };
         };
      } else {
      # autoload disabled -> return undef as the module is not loaded yet (programmer
      # should have it loaded manually)
         $self->mlog (0,"module $module_name is not loaded");
         return undef;
      };
   };
};

### DESTROY (desturctor function which will unload all modules)
sub DESTROY {
   my ($self) = @_;
   my ($module);
   my (@loaded_modules);

   @loaded_modules = keys %{$self->{'modules'}};

   if ($#loaded_modules > 0) {

      $self->mlog(99, "App::Modular is going to be destroyed, ".
                      "modules left to destroy");
      foreach $module (@loaded_modules) {
         $self->mlog(99, " -> $module");
      }

      $self->modules_deregister_all();

   } else {
      $self->mlog(99, "App::Modular finishing, no modules left to unload");
   }
   return;
};

# return with something well-defined
1;

##################################
##        DOCUMENTATION         ##
##################################
=pod

=head1 NAME

B<App::Modular> - modularization framework for perl programs

=head1 SYNOPSIS

	package App::Modular::Module::Test;

	use base qw(App::Modular::Module);

	sub say_hello {
   		print "Hello, dear user!";
	};



	package main;

	use App::Modular;

	my $modul = instance App::Modular;

	$modul->module('Test')->say_hello();

	exit;

=head1 DESCRIPTION

App::Modular aims to provide a framework which should it make very
easy to programmes to create any kind of modular program.

It supports:

=over 4

=item * module dependency solving

=item * autoloading of modules

=item * event handling (implemented as a contributed App::Modular module)

=back

=head1 USAGE

The usage description is split into two parts, one describing what the 
main program has to do in order to work with App::Modular, one describing
how to create a module. The explanation is based on an example; I 
suggest you to try to build a little modular script yourself and you'll
soon understand how App::Modular works.
First, we will create a little module that we'll use in the main program
to greet the user.

=head2 A sample Module

Modules come in the form of perl modules; however, they are not expected
to be in one of the inlcude (@INC) directories, but rather in a specific
directory like "/usr/local/lib/app-modular/sample". Their extension does
not default to ".pm" but to ".mom" (App::Modular Module).

Every module should have C<App::Modular::Module> as a base class, as it
inherits some basic methods then automatically. As a package namespace,
you MUST use C<App::Modular::Module::*>, as App::Modular converts the
package/file name in a way that would brake otherwise.

But now, that's enough talking - let's proceed to some real code:

	#!/usr/bin/perl -w
	# File: Printer.mom
	use strict;

	package App::Modular::Module::Printer;

	use base qw(App::Modular::Module);

	sub printer { 
   		shift;
   		App::Modular->instance()->mlog(99, "printer printing!");
   		print(join ' ', @_); 
	};

	1;

As you will have noticed, the module only provides one method - a method
to print a string or an array to stdout. That's not really much. Anyway,
it's enough for our first test: we can see some action.

=head2 Main Program



( run in 1.238 second using v1.01-cache-2.11-cpan-e1769b4cff6 )