当前位置:  开发笔记 > 编程语言 > 正文

如何有条件地定义Perl子例程?

如何解决《如何有条件地定义Perl子例程?》经验,为你挑选了4个好方法。

我想定义一个Perl函数(称之为"差异"),它取决于命令行参数.以下代码不起作用:

if ("square" eq $ARGV[0]) {sub difference {return ($_[0] - $_[1]) ** 2}}
elsif ("constant" eq $ARGV[0]) {sub difference {return 1}}

似乎忽略了条件,因此无论$ ARGV [0]的值如何,"差异"函数都会得到第二个定义.

我可以通过在函数中添加一个条件来使代码工作:

sub difference {
  if ("square" eq $ARGV[0]) {return ($_[0] - $_[1]) ** 2}
  elsif ("constant" eq $ARGV[0]) {return 1}
}

但这并不是我的意图 - 我不需要在执行期间每次评估条件.我只需要一种方法来影响函数的定义.

我的问题是:

    为什么第一个结构不起作用?

    为什么它没有给出错误,或者其他迹象表明出现了问题?

    有没有办法在Perl中有条件地定义函数?

Ryan Bright.. 24

其他人已经提出了您请求的语法,但我建议为此使用更明确的子例程引用,以便您可以在不操作定义的情况下自由地操作引用.例如:

sub square_difference { return ($_[0] - $_[1]) ** 2 }
sub constant_difference { return 1 }

my %lookup = (
    'square' => \&square_difference,
    'constant' => \&constant_difference,
);

my $difference = $lookup{$ARGV[0]} || die "USAGE: $0 square|constant\n";
print &$difference(4, 1), "\n";

它是相同的基本方法,但我认为这种语法可以让你更方便地将参数映射到子程序.请注意,如果您遇到这种情况,这是战略模式的变体.



1> Ryan Bright..:

其他人已经提出了您请求的语法,但我建议为此使用更明确的子例程引用,以便您可以在不操作定义的情况下自由地操作引用.例如:

sub square_difference { return ($_[0] - $_[1]) ** 2 }
sub constant_difference { return 1 }

my %lookup = (
    'square' => \&square_difference,
    'constant' => \&constant_difference,
);

my $difference = $lookup{$ARGV[0]} || die "USAGE: $0 square|constant\n";
print &$difference(4, 1), "\n";

它是相同的基本方法,但我认为这种语法可以让你更方便地将参数映射到子程序.请注意,如果您遇到这种情况,这是战略模式的变体.



2> Leon Timmerm..:

您想要做的事情可以像这样实现:

if ($ARGV[0] eq 'square') {
    *difference = sub { return ($_[0] - $_[1]) ** 2 };
}
elsif ($ARGV[0] eq 'constant') {
    *difference = sub { return 1 };
}



3> Chris Lutz..:

我个人并没有做过很多这样的事情,但你可能想用一个变量来保存子程序:

my $difference;
if ("square" eq $ARGV[0]) {$difference = sub {return ($_[0] - $_[1]) ** 2}}
elsif ("constant" eq $ARGV[0]) {$difference = sub {return 1}}

致电:

&{ $difference }(args);

要么:

&$difference(args);

或者,正如Leon Timmermans所建议的那样:

$difference->(args);

一些解释 - 这声明了一个名为的变量,$difference并根据您的条件将其设置为保存对匿名子例程的引用.所以你必须取消引用 $difference作为子程序(因此&在前面),以便它调用子程序.

编辑:代码测试和工作.

还有一个编辑:

耶稣,我习惯了useING strictwarnings我忘了他们是可选的.

不过实话说.永远use strict;use warnings;.这将有助于捕捉这样的事情,并给你很好的有用的错误信息,解释什么是错的.我从来没有在生活中使用调试器因为strictwarnings- 这就是错误检查消息的好坏.他们会抓住这样的各种事情,甚至会给你一些有用的信息,说明他们为什么错了.

所以,无论何时你写东西,无论多小(除非它被混淆),总是use strict;use warnings;.



4> Mathew..:

Subs是在编译时定义的 - >如果你启用了"使用警告",你会看到有关子例程重定义的错误消息.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有