我该如何在Perl中使用宏?

3
我该如何在Perl中使用宏,就像在C语言中一样?
示例:
#define value 100 
print value; 

我希望得到输出结果为100。

4
你为什么想在Perl中使用宏?对于你所尝试做的任何事情,可能有许多其他更好的高级语言功能可供选择。 - brian d foy
是的:这是一个例子,你不需要宏:“use constant value => 100; print value;”就可以了。你实际上需要宏的情况是一些类似于assert()的构造,比如print "$condition failed!\n" if (!$condition); - U. Windl
4个回答

31
如果你只是想定义常量(就像例子中一样),而不是完整的宏,那么有几种Perl的方法可以实现这个目的。
有些人喜欢:
use constant value => 100;
print value;

请注意,'value'是一个子程序,而不是一个'变量'。这意味着您无法在字符串中插值,因此您必须执行以下操作:print "The value is ".value."\n";
"最佳实践"的团体喜欢:
use Readonly;
Readonly my $value => 100;
print $value;

然而,与常量不同的是,Readonly 不是 Perl 核心发行版的一部分,因此需要从 CPAN 安装。


常量很难插入到字符串中,还有其他问题。请使用只读(Readonly) - Duncan
4
Duncan说:如果常量为假,则编译时将完全优化掉“if(someconst){...}”。但只读变量不是这种情况。此外,如果您坚持使用只读变量,请务必安装Readonly::XS! - tsee
@tsee,听起来像是微观优化。我相信if(0)已经足够快了;除此之外,OP并没有要求使用#ifdef。请参阅http://search.cpan.org/perldoc?Readonly#COMPARISON_WITH_"use_constant" - use constant存在大量问题。 - rjh
2
@rjh:我不同意Readonly文档中的大部分批评。此外,编译时行为意味着您还可以节省代码的OP结构的内存。关于if(0):你错了:使用Readonly(至少是纯Perl版本),您实际上每次访问都要支付至少一个子例程调用。由于子例程调用非常缓慢,这是很多。如果您考虑像''Readonly my $DEBUG''这样的东西,并且在调试输出方面自由使用它,那么您将在运行时付出昂贵的代价。 - tsee
2
常量并不是很难插入到字符串中。它们可能有点烦人,但并不难。 - brian d foy
显示剩余3条评论

14

Perl不是C语言。学习相应的Perl习语(例如已经提到的use constant value => 100)比试图将C语言习惯用法引入Perl更加有用。


10

对于常量,一种常用的方式是使用一个常量子例程,这将被编译器内联:

use constant value => 100;
或者
sub value () {100}

-2
尝试以下内容:

macro.pl

    use strict;
    use warnings;
    #define a 10;
    print a;

使用-P开关运行此代码。

例如: perl -P macro.pl

同时也要使用模块Filter::cpp


9
来自perlrun手册页面的内容:“注意:由于其固有问题(包括可移植性差),强烈不建议使用-P选项。” - Gavin Brock
11
虽然这个回答从技术上回答了这个问题,但最好提到当使用-P标志将整个perl脚本通过C预处理器运行时会变得多么混乱。实际上,perlrun手册以粗体字写道:“注意:强烈不建议使用-P,因为它存在固有问题,包括可移植性差。它已被弃用,并将在未来的Perl版本中删除。” - msw
3
@Gavin - “P”代表“生产”吗? :) - DVK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接