如何格式化我的Perl代码,以便我可以从命令窗口更改调用,并测试或不测试它?
我所拥有的:详细说明一下,我目前有一个主函数,用于指定源目录和目标归档目录。在每个月末,必须将上个月的数据移动到存档目录中。我已经把所有这些都弄清楚了。子例程使用localtime函数选择本地时间,然后在我测试了一些条件后,它返回上一个月和年份作为归档目录中新文件夹的名称 我需要的是:我在子程序中有一个测试设置,当$test=1时,测试运行并指定我可以输入的唯一年份和月份,而当test=0时,测试不运行,代码正常工作。我希望能够将文件名写入代码外的命令行,并进行某种初始化,以激发我是否运行测试(如perl-e archive.pl 1运行测试,perl-e arhcive.pl 0正常运行代码) 我是Perl的新手,但下面是我的子程序:如何格式化我的Perl代码,以便我可以从命令窗口更改调用,并测试或不测试它?,perl,input,command,prompt,localtime,Perl,Input,Command,Prompt,Localtime,我所拥有的:详细说明一下,我目前有一个主函数,用于指定源目录和目标归档目录。在每个月末,必须将上个月的数据移动到存档目录中。我已经把所有这些都弄清楚了。子例程使用localtime函数选择本地时间,然后在我测试了一些条件后,它返回上一个月和年份作为归档目录中新文件夹的名称 我需要的是:我在子程序中有一个测试设置,当$test=1时,测试运行并指定我可以输入的唯一年份和月份,而当test=0时,测试不运行,代码正常工作。我希望能够将文件名写入代码外的命令行,并进行某种初始化,以激发我是否运行测试(
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)包含到我的子例程中,并且我有所有其他条件,那么我可以让它完美地工作。但是如果我尝试使用my$test=$ARGV[0];进入主程序后,它停止工作。这就是我试图将其调用到子例程中的原因。@user3799015,我必须查看您的代码才能找到答案。您的脚本顶部确实有use strict
和use warnings
,对吗?他们指出错误。如果您将其取出,错误仍然存在,但消息不会显示,并且可能会导致其他问题。是的,我会。这些代码运行正常,我只是不认为它的功能完全符合我的预期,除非我在子程序中包含整个代码。刚才有人告诉我,从子程序进行测试是一种不好的做法。如果我只是通过在命令行中输入--test来执行测试,那么我如何访问测试设置的条件?使用--test执行代码是否只是将test的值设置为1?