从Module实现不同的行为

时间:2016-07-06 15:31:43

标签: perl

我有以下Perl模块:

package Log;

use strict;
use warnings;

# Packaging
use Exporter;
use vars qw( $VERSION @ISA @EXPORT  );

$VERSION   = '1.0.0';
@ISA       = qw( Exporter );
@EXPORT    = qw(Log_Send);

my %log_g = ('PathDirFileLog' => '/some/path',
             'File'           => undef);

# Init
PrivateLog_OpenFileLog();
print("Do not execute this code unless I want from main.pl\n");

END {
    PrivateLog_CloseFileLog();
}


# Public Functions 

sub Log_Send
{
    my ($message) = @_;

    # Cleaning $message
    $message =~ s/\n+$//g;
    $message =~ s/\n/\*/g;

    print($message);
    print({$log_g{'File'}} $message) if ($log_g{'File'});
    return (1);
}

# Private Functions 

sub PrivateLog_OpenFileLog
{
    my $path = $log_g{'PathDirFileLog'}.'/global.log';

    if (!$log_g{'File'}) {
        if (!open($log_g{'File'}, '>>', $path)) {
            $log_g{'File'} = undef;
            Log_Send("Failed to open '$path' in '>>' mode : $!");
            return (0);
        }
        select((select($log_g{'File'}), $|=1)[0]);
    }
    return (1);
}

sub PrivateLog_CloseFileLog
{
    if ($log_g{'File'}) {
        close($log_g{'File'});
        $log_g{'File'} = undef;
    }
    return (1);
}

1; 

我输入“使用日志”时会立即执行打印。从任何Perl脚本。有时候这个打印必须在这里,有时候不会(这种情况适用于我写的其他模块)。

有没有办法从每个实例中“激活”或“停用”此脚本?

#!/usr/bin/perl -w

use strict;
use warnings;

use Log;

Log_Send("Hello world !");

就像我导入的所有模块上的“启用/禁用”调试一样,有办法吗?

编辑:我试图实现自己的import sub,但要么我丢失了@EXPORT机会,要么我从Exporter复制/粘贴源代码,我什么都不懂。如果有一个用@EXPORT这样的机制实现“导入”的教程,我会很高兴。

2 个答案:

答案 0 :(得分:1)

调用use意味着从模块的命名空间调用import。制作一个import函数,将print移入其中并使其接受表示不需要print的标记。

答案 1 :(得分:0)

您在评论中指出决定代码是否应该执行的因素是基于正在执行的脚本的名称。我发现这个特别奇怪,而且设计非常糟糕,但它是可以实现的,因为正在执行的脚本的路径可以在$0中找到。

use File::Basename qw( basename );

if (basename($0) eq 'main.pl') {
   ...
}

我认为以下界面更合适:

use Carp     qw( );
use Exporter qw( );

sub import {
   my $class = shift;

   my $saw_opts = 0;
   while (@_ && $_[0] =~ /^-/) {
      $saw_opts = 1;
      my $opt = shift(@_);
      if ($opt eq '--debug') {
         ...
      }
      elsif ($opt eq '--') {
         last;
      }
      else {
         Carp::croak("Unknown option $opt\n");
      }
   }

   return if $saw_opts && !@_;

   unshift @_, $class;
   goto &Exporter::import;
}

您可以按如下方式使用它:

use Log qw( --debug );
use Log;

  -or-

use Log qw( --debug :DEFAULT );

第二个想法,我认为那很糟糕。不需要任何神奇的东西。只需创建一个可以执行所需操作的子程序,并从脚本中调用它。

use Log;
Log::init( debug => 1 );