如何格式化我的Perl代码,以便我可以从命令窗口更改调用,并测试或不测试它?

如何格式化我的Perl代码,以便我可以从命令窗口更改调用,并测试或不测试它?,perl,input,command,prompt,localtime,Perl,Input,Command,Prompt,Localtime,我所拥有的:详细说明一下,我目前有一个主函数,用于指定源目录和目标归档目录。在每个月末,必须将上个月的数据移动到存档目录中。我已经把所有这些都弄清楚了。子例程使用localtime函数选择本地时间,然后在我测试了一些条件后,它返回上一个月和年份作为归档目录中新文件夹的名称 我需要的是:我在子程序中有一个测试设置,当$test=1时,测试运行并指定我可以输入的唯一年份和月份,而当test=0时,测试不运行,代码正常工作。我希望能够将文件名写入代码外的命令行,并进行某种初始化,以激发我是否运行测试(

我所拥有的:详细说明一下,我目前有一个主函数,用于指定源目录和目标归档目录。在每个月末,必须将上个月的数据移动到存档目录中。我已经把所有这些都弄清楚了。子例程使用localtime函数选择本地时间,然后在我测试了一些条件后,它返回上一个月和年份作为归档目录中新文件夹的名称

我需要的是:我在子程序中有一个测试设置,当$test=1时,测试运行并指定我可以输入的唯一年份和月份,而当test=0时,测试不运行,代码正常工作。我希望能够将文件名写入代码外的命令行,并进行某种初始化,以激发我是否运行测试(如perl-e archive.pl 1运行测试,perl-e arhcive.pl 0正常运行代码)

我是Perl的新手,但下面是我的子程序:

sub dateDirectory {
    my $lt = localtime();            # establish a variable lt for the localtime (includes, sec, min, hour, mday, mon, year)
    my $year = $lt->year+1900;       # establish a variable year and add 1900 to it as it prints only 100+ value
    my $mon = $lt->mon+1;            # establish a variable mon for month and add 1 as it is a zero-indexed language

    my $test = 1; # establish the test variable to run a unit test if test = 1 and don't run it if test = 0

    if ($test == 1) {
        $year = 2005;
        $mon = 3;
    }

    my $prev_mon = $mon - 1;
    my $prev_year = $year - 1;
    my $prev_yearmonth = "year$prev_mon";

    if ($mon == 1) {
        $prev_mon = 12;
        $year = $prev_year;
        $prev_yearmonth = "$year$prev_mon";
    }

    my $prev_monlength = length($prev_mon);

    if ($prev_monlength == 1) {
        $prev_yearmonth = sprintf "%d%02d", $year, $prev_mon;
    }

    return ($prev_yearmonth);
}

使用
@ARGV
访问传递给perl脚本的参数

在这种情况下,我建议您使用以捕获用于触发特殊处理的参数:

use strict;
use warnings;

use Getopt::Long;

GetOptions(
    'test'   => \my $test,
);

print $test ? "In Testing mode\n" : "Regular mode\n";
然后,当您希望处于测试模式时,只需执行以下脚本:

perl yourscript.pl --test

正如Miller所说,
Getopts::Long
是为perl程序提供命令行选项的好方法。但是,我想添加一个示例,说明如何使用参数将
$test
设置为0或1

#!/usr/bin/perl

use strict;
use warnings;

my $test = $ARGV[0];

if ( not defined $test ) {
    die "please supply an argmument";
}

if ( $test == 1 ) {
    print "test mode\n";
} else {
    print "normal mode\n";
}

<尝试调用它>代码> Perl Test.PL 0 < /C>和<代码> Perl Test.PL 1 < /C> > < /P> < P>您可以考虑学习使用CPAN,并安装该模块。它使各种各样的日期数学很容易以正确的方式进行

use Carp qw< croak >;
use DateTime;

sub dateDirectory {
    my ($year, $month) = @_;

    # croak throws an exception at the calling function.
    croak "dateDirectory requires both year and month or neither be specified\n"
        if (
            ($year && !$month)
         || (!$year && $month)
        );

    # Get default value of "last month", if not specified.
    if( !$year ) {
        my $date = DateTime->now()->subtract( months => 1 );

        $year = $date->year();
        $month = $date->month();
    }

    return "%04d%02d", $year, $month;
}
使用Carp qw;
使用日期时间;
子日期目录{
我的($年,$月)=@;
#croak在调用函数时抛出异常。
croak“dateDirectory要求同时指定年和月,或者两者都不指定\n”
如果(
($year&!$month)
||(!$年和$月)
);
#如果未指定,则获取默认值“last month”。
如果(!$年){
my$date=DateTime->now()->减法(月=>1);
$year=$date->year();
$month=$date->month();
}
返回“%04d%02d”,$year,$month;
}

您可以编写测试代码,用您想要的任何年份和月份调用dateDirectory。

我喜欢perl,但我使用了带有cron的log rotate来代替这个基本函数


我一定会安装模块的,谢谢!:)测试代码肯定很好。欢迎使用StackOverflow!如果您在答案中发布链接中的相关引用,这将非常有用,这样用户就不必去搜索它们。我看到了Getopts::Long的用法,但我认为您的解决方案最适合我的问题。然而,我已经玩了几天了,不知道如何将输入测试参数合并到主例程中,同时将条件合并到子例程中。我试着把$test=@;进入子程序,从主函数调用我的输入,但它不起作用。
@
是一个数组,您在标量上下文中调用它。尝试
my($test)=@use strict
use warnings
,对吗?他们指出错误。如果您将其取出,错误仍然存在,但消息不会显示,并且可能会导致其他问题。是的,我会。这些代码运行正常,我只是不认为它的功能完全符合我的预期,除非我在子程序中包含整个代码。刚才有人告诉我,从子程序进行测试是一种不好的做法。如果我只是通过在命令行中输入--test来执行测试,那么我如何访问测试设置的条件?使用--test执行代码是否只是将test的值设置为1?