如何格式化我的 Perl 代码,以便我可以从命令窗口更改我的调用并测试或不测试它?
Posted
技术标签:
【中文标题】如何格式化我的 Perl 代码,以便我可以从命令窗口更改我的调用并测试或不测试它?【英文标题】:How to format my Perl code such that I can alter my calling from the command window and either test or not test it? 【发布时间】:2014-07-02 21:11:33 【问题描述】:我所拥有的:详细地说,我目前有一个指定源目录和目标存档目录的 main 函数。每个月底,必须将上个月的数据移到归档目录中。我已经把这一切都弄清楚了。子例程是使用 localtime 函数选择本地时间,然后在我测试一些条件后,它返回上个月和上一年作为存档目录中新文件夹的名称。
我需要什么:我在子例程中有一个测试设置,当 $test = 1 时,测试运行并指定我可以输入的唯一年份和月份,而当 test = 0 时,测试没有t 运行,代码正常工作。我希望能够将文件的名称写入代码之外的命令行,并且无论我是否运行测试(比如 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);
【问题讨论】:
【参考方案1】:使用@ARGV
访问传递给 perl 脚本的参数。
在这种情况下,我建议您使用Getopts::Long
来捕获旨在触发您的特殊处理的参数:
use strict;
use warnings;
use Getopt::Long;
GetOptions(
'test' => \my $test,
);
print $test ? "In Testing mode\n" : "Regular mode\n";
然后,当您想处于测试模式时,只需执行如下脚本即可:
perl yourscript.pl --test
【讨论】:
如果我只是通过在命令行中输入 --test 来执行我的测试,我如何访问测试设置的条件? 使用 --test 执行代码是否只是将 test 的值设置为 1?【参考方案2】:就像 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
和perl test.pl 1
。
【讨论】:
我看到了 Getopts::Long 的使用,但我认为您的解决方案最适合我的问题。但是,我已经玩了几天了,无法弄清楚如何将输入测试参数合并到主例程中,同时将条件合并到子例程中。我试着把我的 $test = @_;进入子例程以从主函数调用我的输入,但它不起作用。@_
是一个数组,您在标量上下文中调用它。尝试my ($test) = @_;
,如果这不起作用,您可以发布一些代码并提出另一个问题。
不,那没用。如果我将你的整个代码(减去 use strict 和 use 警告)包含在我的子程序中,我可以让它完美地工作,我有所有其他条件。但是如果我尝试使用 my $test = $ARGV[0];部分进入主程序,它停止工作。这就是为什么我试图将它调用到子程序中。
@user3799015,我必须查看您的代码才能弄清楚。您的脚本顶部确实有use strict
和use warnings
吗?他们指出错误。如果你把它们拿出来,错误仍然存在,但消息不会显示,它们可能会导致其他问题。
是的,我愿意。代码正常运行我只是不认为它完全按照我想要的方式运行,除非我将整个代码包含在子例程中。我刚刚被告知从子程序进行测试是不好的做法。【参考方案3】:
您可能想考虑学习使用 CPAN,并安装 DateTime 模块。它可以以正确的方式轻松完成各种日期数学运算。
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;
您可以编写测试代码,使用您想要的任何年份和月份调用 dateDirectory。
【讨论】:
我一定会安装模块谢谢! :) 确定测试代码会很好。【参考方案4】:我喜欢 perl,但我使用了带有 cron 的 log rotate 来代替这个基本功能。
http://www.adminschoice.com/crontab-quick-reference/
http://linuxcommand.org/man_pages/logrotate8.html
【讨论】:
欢迎来到 ***!如果您在答案中发布链接中的相关引用,这将很有用,这样用户就不必去搜索它们了。以上是关于如何格式化我的 Perl 代码,以便我可以从命令窗口更改我的调用并测试或不测试它?的主要内容,如果未能解决你的问题,请参考以下文章