加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何通过命令行开关为我的Perl程序启用调试模式?

发布时间:2020-12-15 21:47:37 所属栏目:大数据 来源:网络整理
导读:我正以“头脑优先”的方式学习Perl.我绝对是这种语言的新手: 我试图从CLI调用debug_mode,通过“打开和关闭”某些子程序来控制我的脚本的工作方式. 以下是我到目前为止所得到的: #!/usr/bin/perl -s -w# purpose : make subroutine execution optional,# wh
我正以“头脑优先”的方式学习Perl.我绝对是这种语言的新手:

我试图从CLI调用debug_mode,通过“打开和关闭”某些子程序来控制我的脚本的工作方式.

以下是我到目前为止所得到的:

#!/usr/bin/perl -s -w

# purpose : make subroutine execution optional,# which is depending on a CLI switch flag

use strict;
use warnings;

use constant DEBUG_VERBOSE             => "v";
use constant DEBUG_SUPPRESS_ERROR_MSGS   => "s";
use constant DEBUG_IGNORE_VALIDATION     => "i";
use constant DEBUG_SETPPING_COMPUTATION  => "c";

our ($debug_mode);

mainMethod();

sub mainMethod # ()
{
    if(!$debug_mode)
    {
        print "debug_mode is OFFn";
    }
    elsif($debug_mode)
    {
        print "debug_mode is ONn";
    }
    else
    {
        print "OMG!n";
        exit -1;
    }

    checkArgv();
    printErrorMsg("Error_Code_123","Parsing Error at...");
    verbose();
}

sub checkArgv #()
{
    print ("Number of ARGV : ".(1 + $#ARGV)."n");
}

sub printErrorMsg # ($error_code,$error_msg,..)
{
    if(defined($debug_mode) && !($debug_mode =~ DEBUG_SUPPRESS_ERROR_MSGS))
    {
        print "You can only see me if -debug_mode is NOT set".
          " to DEBUG_SUPPRESS_ERROR_MSGSn";
        die("terminated prematurely...n") and exit -1;
    }
}

sub verbose # ()
{
    if(defined($debug_mode) && ($debug_mode =~ DEBUG_VERBOSE))
    {
        print "Blah blah blah...n";
    }
}

据我所知,至少它有效……:

> -debug_mode开关不会干扰正常的ARGV
>以下命令行有效:

> ./optional.pl
> ./optional.pl -debug_mode
> ./optional.pl -debug_mode = v
> ./optional.pl -debug_mode = s

但是,当多个debug_modes“混合”时,我很困惑,例如:

> ./optional.pl -debug_mode = sv
> ./optional.pl -debug_mode = vs

我不明白为什么上面的代码行“神奇地起作用”.

我看到“DEBUG_VERBOS”和“DEBUG_SUPPRESS_ERROR_MSGS”都适用于脚本,在这种情况下这很好.

但是,如果存在一些“冲突”的调试模式,我不确定如何设置“debug_modes的优先级”?

另外,我不确定我的方法对于Perlists是否足够好,我希望我能够朝着正确的方向前进.

一个最大的问题是我现在把if语句放在里面
我的大部分子程序用于控制不同模式下的行为.这个可以吗?
有更优雅的方式吗?

我知道必须有来自CPAN或其他地方的调试模块,但我想要一个真正的最小解决方案,它不依赖于除“默认”之外的任何其他模块.

而且我无法控制执行此脚本的环境……

解决方法

要处理命令行选项,请查看 Getopt::Long.您将获得各种灵活的参数解析选项.

有许多模块可以处理日志记录. Log4Perl是一个非常流行的记录模块.

如果你真的,真的想通过避免CPAN来限制自己(这是一个坏主意),你可以很容易地将一个记录模块放在一起.

这是我为你砍的一小部分.它需要测试和真实的文档等等.我还使用了一些高级技术,比如自定义import()方法.围绕我使用单个变量来存储整个应用程序的DEBUG设置也存在一些问题.但它的确有效.我在一个项目中使用了类似的模块,并对它非常满意.

package QLOG;

use strict;
use warnings;
use Carp qw(croak);

our %DEBUG_OPTIONS;
our %VALID_DEBUG_OPTIONS;
our %DEBUG_CONFLICTS;

sub import {

    my $pkg = shift;
    my $target = caller();

    my %opts = @_;


    # Configure options

    croak "Must supply an array ref of valid modes"
       unless exists $opts{options};

    @VALID_DEBUG_OPTIONS{ @{$opts{options}} } = ();

    # Configure conflicts

    if( exists $opts{conflicts} ) {
        @DEBUG_CONFLICTS{ keys %{$opts{conflicts}} } 
            = values %{$opts{conflicts}}
    }

    # Export DEBUG method

    {   no strict 'refs';
        *{$target.'::DEBUG'} = &;DEBUG;
    }

    return;
}

sub DEBUG {
    my $mode = shift;

    croak "DEBUG mode undefined"
        unless defined $mode;

    return unless
        ( $mode eq 'ANY' and %DEBUG_OPTIONS )
        or exists $DEBUG_OPTIONS{$mode};

    warn "$_n" for @_;

    return 1;
}


sub set_options {

    for my $opt ( @_ ) {
        die "Illegal option '$opt'"
           unless exists $VALID_DEBUG_OPTIONS{$opt};

        $DEBUG_OPTIONS{$opt}++;
    }

    return;
}

sub check_option_conflicts {

    for my $opt ( keys %DEBUG_OPTIONS ) {

        if (exists $DEBUG_CONFLICTS{$opt}) {

            for ( @{$DEBUG_CONFLICTS{$opt}} ) {

                die "Debug option $opt conflicts with $_" 
                    if exists $DEBUG_OPTIONS{$_} 
            }
        }
    }

    return;
}


1;

然后像这样使用它:

#!/usr/bin/perl 

use strict;
use warnings;


use Getopt::Long;

use QLOG
    options => [qw(
        VERBOSE
        SUPPRESS_ERROR_MSGS
        IGNORE_VALIDATION
        SETPPING_COMPUTATION
    )],conflicts => {
        VERBOSE => [qw(
            SUPPRESS_ERROR_MSGS
            SETPPING_COMPUTATION
        )],};




process_args();

DEBUG VERBOSE => 'Command line data parsed.';

main();

### ---------------

sub main {

    DEBUG VERBOSE => 'BEGIN main()';

    if( DEBUG 'ANY' ) {
        print "debug_mode is ONn";
    }
    else {
        print "debug_mode is OFFn";
    }

    warn "Error which could be surpressedn"
        unless DEBUG 'SUPPRESS_ERROR_MSGS';
}


# Get arguments and process flags like 'v' and 'sc' into strings specified
# in QLOG configuration above.
# This processing makes the nice DEBUG VERBOSE => 'blah'; syntax work.
sub process_args {

    # Use Getopt::Long to parse @ARGV

    my @debug_options;
    GetOptions (
        'debug-options=s@' => @debug_options,'help'             => &;usage,) or usage();

    # Convert option flags to strings.
    my %option_lut = qw(
        v  VERBOSE  
        s  SUPPRESS_ERROR_MSGS
        i  IGNORE_VALIDATION 
        c  SETPPING_COMPUTATION 
    );

    my @options = map {          # This chained map 
        exists $option_lut{$_}   #    looks in the lut for a flag
        ? $option_lut{$_}        #       translates it if found
        : $_                     #       or passes on the original if not.
    } 
    map {                        # Here we split 'cv' into ('c','v')
       split //
    } @debug_options;

    # Really should use Try::Tiny here.
    eval {    
        # Send a list of strings to QLOG
        # QLOG will make sure they are allowed.
        QLOG::set_options( @options );

        QLOG::check_option_conflicts(); 

        1;          # Ensure true value returned if no exception occurs.
    } or usage($@);

    return;
}

sub usage {

    my $message = shift || '';
    $message = '' if $message eq 'help';

    print <<"END";
$message

Use this proggy right.

END

    exit;
}

您可能希望添加一个方法以使您的调试消息可以抑制.

就像是:

sub SUPPRESSED_BY {
     my $mode = shift;

     return if exists $DEBUG_OPTIONS{$mode);

     return @_; 
}

导出符号然后使用它:

DEBUG VERBOSE => SUPPRESSED_BY SUPPRESS_ERRORS => 'My message here';

将日志记录模块放在一起的容易性导致存在大量可用的这种模块.有很多方法可以完成这项任务,并且在检测代码时需要有不同的变化,甚至更多.我甚至编写了一些记录模块来满足各种需求.

无论如何,当你首先潜入Perl时,这应该会给你一个严重的扣篮.

随意问我’到底是什么?’输入问题.我意识到我在向你扔了很多东西.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读