【发布时间】:2015-01-06 15:05:38
【问题描述】:
我必须在 Perl 中使用命令行参数来初始化全局变量,然后将其传递给一组包以设置这些包中变量的值。如果假设我的主程序是带有 $opt_n 参数的 main.pl 并且包是 a.pm、b.pm 和 c.pm,我该怎么做。
请帮忙。
【问题讨论】:
-
您考虑过/尝试过什么?
标签: perl
我必须在 Perl 中使用命令行参数来初始化全局变量,然后将其传递给一组包以设置这些包中变量的值。如果假设我的主程序是带有 $opt_n 参数的 main.pl 并且包是 a.pm、b.pm 和 c.pm,我该怎么做。
请帮忙。
【问题讨论】:
标签: perl
最简单的解决方案:在每个包中,创建一个setter方法:
package a;
our $global_for_a;
sub set_global_a { $global_for_a = shift; }
1;
#### Your main.pl
# Process GetOpt
a::set_global_a($opt_n);
还有一些更有趣的东西(例如,根据加载的包列表自动调用 setter),但这是为了解 Perl 内部结构的高级用户准备的。
另一种选择是直接访问 main 的值:
# Old code in a.pm
do_stuff($global_for_a);
# Instead, use Main's global:
do_stuff($main::opt_n);
【讨论】:
有很多方法可以实现您的目标。第一步是将命令行参数放入 main.pl 中的变量中。命令行参数可通过预定义的 perl 列表变量 @ARGV 获得。假设只有一个命令行参数,以下将起作用:
my $opt_n = $ARGV[0];
最好检查是否提供了正确数量的命令行参数。例如,
if (not @ARGV) {die "No command line arguments were supplied.\n";}
if (scalar(@ARGV) > 1) {die "Too many command line arguments were supplied.\n";}
my $opt_n = $ARGV[0];
如果您希望有多个命令行参数,使用 shift 运算符会很方便。
my $opt_n = shift @ARGV;
my $opt_o = shift @ARGV;
if (not defined $opt_o) {die "Too few command line arguments.\n";}
要在其他包中使用 $opt_n 的值,您有两个选择:1) 使 $opt_n 全局化('our $opt_n' 而不是 'my $opt_n'),或 2) 将 $opt_n 从将 $opt_n 存储在其他包可访问的变量中的其他包。全局变量路由更简单,但会产生更多相互依赖和复杂的代码。如果你想这样做,只需参考其他包中的'$::opt_n'即可。
使用第二种方法,您将从 main.pl 调用 A.pm 子例程。
A::set_opt_n($opt_n);
在 A.pm 中,你会这样写:
package A;
use strict;
my $opt_n;
sub set_opt_n($)
{
my ($opt_n_from_main) = @_;
$opt_n = $opt_n_from_main;
return;
}
从 main.pl 调用 set_opt_n 后,可以在 A.pm 中使用 $opt_n。当然,main.pl 中的 $opt_n 和 A.pm 中的 $opt_n 是两个不同的变量。如果一个的值改变,另一个不会自动改变。这与使用单个全局变量 $::opt_n(或 $main::opt_n)非常不同。
【讨论】: