perltidy code and add .perltidyrc to repo
[p5sagit/Log-Contextual.git] / lib / Log / Contextual.pm
index 0296af3..9e8ca08 100644 (file)
@@ -11,11 +11,6 @@ use Exporter::Declare;
 use Exporter::Declare::Export::Generator;
 use Data::Dumper::Concise;
 use Scalar::Util 'blessed';
-use Log::Contextual::Router;
-
-my @dlog = ((map "Dlog_$_", @levels), (map "DlogS_$_", @levels));
-
-my @log = ((map "log_$_", @levels), (map "logS_$_", @levels));
 
 eval {
    require Log::Log4perl;
@@ -25,105 +20,144 @@ eval {
 
 # ____ is because tags must have at least one export and we don't want to
 # export anything but the levels selected
-sub ____ {}
+sub ____ { }
 
-exports ('____',
-   @dlog, @log,
-   qw( set_logger with_logger )
-);
+exports(qw(____ set_logger with_logger ));
 
 export_tag dlog => ('____');
 export_tag log  => ('____');
 import_arguments qw(logger package_logger default_logger);
 
-sub arg_router { return $_[1] if defined $_[1]; our $Router_Instance ||= Log::Contextual::Router->new }
-sub arg_logger { $_[1] }
-sub arg_levels { $_[1] || [qw(debug trace warn info error fatal)] }
+sub router {
+   our $Router_Instance ||= do {
+      require Log::Contextual::Router;
+      Log::Contextual::Router->new
+     }
+}
+
+sub arg_logger         { $_[1] }
+sub arg_levels         { $_[1] || [qw(debug trace warn info error fatal)] }
 sub arg_package_logger { $_[1] }
 sub arg_default_logger { $_[1] }
 
 sub before_import {
    my ($class, $importer, $spec) = @_;
-   my $router = $class->arg_router;
+   my $router      = $class->router;
+   my $exports     = $spec->exports;
+   my %router_args = (
+      exporter  => $class,
+      target    => $importer,
+      arguments => $spec->argument_info
+   );
 
    die 'Log::Contextual does not have a default import list'
-      if $spec->config->{default};
+     if $spec->config->{default};
+
+   $router->before_import(%router_args);
+
+   $spec->add_export(
+      '&set_logger',
+      sub {
+         my $router = $class->router;
 
-   $router->before_import(@_);
+         die ref($router) . " does not support set_logger()"
+           unless $router->does('Log::Contextual::Role::Router::SetLogger');
+
+         return $router->set_logger(@_);
+      }) if $exports->{'&set_logger'};
+
+   $spec->add_export(
+      '&with_logger',
+      sub {
+         my $router = $class->router;
+
+         die ref($router) . " does not support with_logger()"
+           unless $router->does('Log::Contextual::Role::Router::WithLogger');
+
+         return $router->with_logger(@_);
+      }) if $exports->{'&with_logger'};
 
    my @levels = @{$class->arg_levels($spec->config->{levels})};
    for my $level (@levels) {
       if ($spec->config->{log}) {
-         $spec->add_export("&log_$level", sub (&@) {
-            my ($code, @args) = @_;
-            $router->handle_log_request({
-               package => scalar(caller),
-               caller_level => 1,
-               level => $level,
-            }, $code, @args);
-            return @args;
-         });
-         $spec->add_export("&logS_$level", sub (&@) {
-            my ($code, @args) = @_;
-            $router->handle_log_request({
-               package => scalar(caller),
-               caller_level => 1,
-               level => $level,
-            }, $code, @args);
-            return $args[0];
-         });
+         $spec->add_export(
+            "&log_$level",
+            sub (&@) {
+               my ($code, @args) = @_;
+               $router->handle_log_request(
+                  exporter       => $class,
+                  caller_package => scalar(caller),
+                  caller_level   => 1,
+                  message_level  => $level,
+                  message_sub    => $code,
+                  message_args   => \@args,
+               );
+               return @args;
+            });
+         $spec->add_export(
+            "&logS_$level",
+            sub (&@) {
+               my ($code, @args) = @_;
+               $router->handle_log_request(
+                  exporter       => $class,
+                  caller_package => scalar(caller),
+                  caller_level   => 1,
+                  message_level  => $level,
+                  message_sub    => $code,
+                  message_args   => \@args,
+               );
+               return $args[0];
+            });
       }
       if ($spec->config->{dlog}) {
-         $spec->add_export("&Dlog_$level", sub (&@) {
-            my ($code, @args) = @_;
-            my $wrapped = sub {
-               local $_ = (@_?Data::Dumper::Concise::Dumper @_:'()');
-               &$code;
-            };
-            $router->handle_log_request({
-               package => scalar(caller),
-               caller_level => 1,
-               level => $level,
-            }, $wrapped, @args);
-            return @args;
-         });
-         $spec->add_export("&DlogS_$level", sub (&$) {
-            my ($code, $ref) = @_;
-            my $wrapped = sub {
-               local $_ = Data::Dumper::Concise::Dumper($_[0]);
-               &$code;
-            };
-            $router->handle_log_request({
-               package => scalar(caller),
-               caller_level => 1,
-               level => $level,
-            }, $wrapped, $ref);
-            return $ref;
-         });
+         $spec->add_export(
+            "&Dlog_$level",
+            sub (&@) {
+               my ($code, @args) = @_;
+               my $wrapped = sub {
+                  local $_ = (@_ ? Data::Dumper::Concise::Dumper @_ : '()');
+                  &$code;
+               };
+               $router->handle_log_request(
+                  exporter       => $class,
+                  caller_package => scalar(caller),
+                  caller_level   => 1,
+                  message_level  => $level,
+                  message_sub    => $wrapped,
+                  message_args   => \@args,
+               );
+               return @args;
+            });
+         $spec->add_export(
+            "&DlogS_$level",
+            sub (&$) {
+               my ($code, $ref) = @_;
+               my $wrapped = sub {
+                  local $_ = Data::Dumper::Concise::Dumper($_[0]);
+                  &$code;
+               };
+               $router->handle_log_request(
+                  exporter       => $class,
+                  caller_package => scalar(caller),
+                  caller_level   => 1,
+                  message_level  => $level,
+                  message_sub    => $wrapped,
+                  message_args   => [$ref],
+               );
+               return $ref;
+            });
       }
    }
 }
 
-sub after_import { return arg_router()->after_import(@_) }
-
-sub set_logger {
-   my $router = arg_router();
-   my $meth = $router->can('set_logger');
-
-   die ref($router) . " does not support set_logger()"
-      unless defined $meth;
-
-   return $router->$meth(@_);
-}
-
-sub with_logger {
-   my $router = arg_router();
-   my $meth = $router->can('with_logger');
-
-   die ref($router) . " does not support with_logger()"
-      unless defined $meth;
-
-   return $router->$meth(@_);
+sub after_import {
+   my ($class, $importer, $spec) = @_;
+   my %router_args = (
+      exporter  => $class,
+      target    => $importer,
+      arguments => $spec->argument_info
+   );
+   $class->router->after_import(%router_args);
 }
 
 1;
@@ -581,10 +615,27 @@ The first six merely need to return true if that level is enabled.  The latter
 six take the results of whatever the user returned from their coderef and log
 them.  For a basic example see L<Log::Contextual::SimpleLogger>.
 
+=head1 LOG ROUTING
+
+In between the loggers and the log functions is a log router that is responsible for
+finding a logger to handle the log event and passing the log information to the
+logger. This relationship is described in the documentation for C<Log::Contextual::Role::Router>.
+
+C<Log::Contextual> and packages that extend it will by default share a router singleton that
+implements the with_logger() and set_logger() functions and also respects the -logger,
+-package_logger, and -default_logger import options with their associated default value
+functions. The router singleton is available as the return value of the router() function. Users
+of Log::Contextual may overload router() to return instances of custom log routers that
+could for example work with loggers that use a different interface.
+
 =head1 AUTHOR
 
 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
 
+=head1 CONTRIBUTORS
+
+triddle - Tyler Riddle <t.riddle@shadowcat.co.uk>
+
 =head1 DESIGNER
 
 mst - Matt S. Trout <mst@shadowcat.co.uk>