通过命令行设置的 perl 包变量
perl package variables set through command line
我必须在 Perl 中使用命令行参数来初始化全局变量,然后将其传递给一组包以设置这些包中变量的值。我该怎么做,如果假设我的主程序是 main.pl,参数是 $opt_n,包是 a.pm、b.pm 和 c.pm。
请帮忙。
最简单的解决方案:在每个包中,创建一个 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);
还有更奇特的东西(例如,根据加载的包列表自动调用 setters),但那是为了解 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];
如果您希望有多个命令行参数,使用移位运算符会很方便。
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后,$opt_n可以在A.pm中使用。当然,main.pl中的$opt_n和A.pm中的$opt_n是两个不同的变量。如果其中一个的值改变,另一个不会自动改变。这与使用单个全局变量 $::opt_n(或 $main::opt_n)非常不同。
我必须在 Perl 中使用命令行参数来初始化全局变量,然后将其传递给一组包以设置这些包中变量的值。我该怎么做,如果假设我的主程序是 main.pl,参数是 $opt_n,包是 a.pm、b.pm 和 c.pm。
请帮忙。
最简单的解决方案:在每个包中,创建一个 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);
还有更奇特的东西(例如,根据加载的包列表自动调用 setters),但那是为了解 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];
如果您希望有多个命令行参数,使用移位运算符会很方便。
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后,$opt_n可以在A.pm中使用。当然,main.pl中的$opt_n和A.pm中的$opt_n是两个不同的变量。如果其中一个的值改变,另一个不会自动改变。这与使用单个全局变量 $::opt_n(或 $main::opt_n)非常不同。