用Perl编写宏
我的代码中多次出现这种语句用Perl编写宏,perl,macros,Perl,Macros,我的代码中多次出现这种语句 我想对所有这些语句保持相同的格式,这样当某些内容被更改时,它只在一个地方被更改 在Perl中,我应该如何着手解决这种情况 我应该使用宏还是函数 我见过这么多这样的线程,但它并没有说明如何编写一个像 open $FP, '>', $outfile or die $outfile." Cannot open file for writing\n"; Perl 5实际上没有宏(有源代码过滤器,但它们既危险又难看,甚至我都不会将您链接到文档)。函数可能是正确的选择,
open $FP, '>', $outfile or die $outfile." Cannot open file for writing\n";
Perl 5实际上没有宏(有源代码过滤器,但它们既危险又难看,甚至我都不会将您链接到文档)。函数可能是正确的选择,但您会发现,它使新手更难阅读您的代码。一个更好的选择可能是使用pragma(从Perl 5.10.1开始它是核心),只需删除
或die
部分
如果您使用,另一个选项是使用。您只需键入fwFPoutfile
,它就会生成
#define fw(FP, outfile) open $FP, '>', \
$outfile or die $outfile." Cannot open file for writing\n";
snipMate文本是
open my $FP, '>', $outfile
or die "Couldn't open $outfile for writing: $!\n";
我相信其他编辑器也有类似的功能,但我是Vim用户。首先,您应该这样写:
snippet fw
open my $${1:filehandle}, ">", $${2:filename variable}
or die "Couldn't open $$2 for writing: $!\n";
${3}
包括open
失败的原因
如果你想封装它,你可以写:
open my $FP, '>', $outfile or die "Could not open '$outfile' for writing:$!";
从Perl5.10.1开始,是核心,我将介绍第二个Chas。Owens建议使用它。有几种方法可以处理类似于Perl中C宏的内容:源过滤器、子例程、Template::Toolkit或使用文本编辑器中的功能 源过滤器 如果您必须有一个C/CPP风格的预处理器宏,那么可以使用预编译用Perl(或者,实际上,任何语言)编写一个。您可以编写相当简单到复杂的Perl类,对源代码的文本进行操作,并在代码进入Perl编译器之前对其执行转换。您甚至可以通过CPP预处理器直接运行Perl代码,以获得在C/CPP中使用的宏扩展的确切类型 Damian Conway是Perl核心发行版的一部分。使用Filter::Simple,您可以轻松编写一个简单的模块来执行所描述的宏。例如:
use Carp;
sub openex {
my ($mode, $filename) = @_;
open my $h, $mode, $filename
or croak "Could not open '$filename': $!";
return $h;
}
# later
my $FP = openex('>', $outfile);
然后是一个Perl文件:
package myopinion;
# save in your Perl's @INC path as "myopinion.pm"...
use Filter::Simple;
FILTER {
s/Hogs/Pigs/g;
s/Hawgs/Hogs/g;
}
1;
输出:
use myopinion;
print join(' ',"Hogs", 'Hogs', qq/Hawgs/, q/Hogs/, "\n");
print "In my opinion, Hogs are Hogs\n\n";
如果在中重写过滤器以替换所需的宏,则FILTER::Simple应该可以正常工作。Filter::Simple可以被限制在代码的某些部分,例如可执行部分,而不是POD部分;仅在字符串中;只有在代码中
根据我的经验,源过滤器并没有被广泛使用。我经常看到他们试图加密Perl源代码或幽默的Perl。换句话说,我知道可以这样做,但我个人对它们了解不够,不能推荐或说不要使用它们
子例程
西南努尔是实现这一目标的好方法。我只想补充一点,您将看到的一个常见的老习惯用法涉及传递对typeglob的引用,如下所示:
Pigs Pigs Hogs Pigs
In my opinion, Pigs are Pigs
阅读为什么是这样
模板工具包
可以用来处理Perl源代码。例如,您可以按照以下内容编写模板:
sub opensesame {
my $fn=shift;
local *FH;
return open(FH,$fn) ? *FH : undef;
}
$fh=opensesame('> /tmp/file');
通过Template::Toolkit运行该工具可能会导致扩展和替换到:
[% fw(fp, outfile) %]
Template::Toolkit最常用于将凌乱的HTML和其他表示代码与web应用程序中的应用程序代码分离。Template::Toolkit是非常积极开发的,并且有很好的文档记录。如果您只使用您所建议的类型的宏,那么这可能有点过头了
文本编辑器
查斯。欧文斯有一个使用维姆。我使用BBEdit,可以很容易地编写一个文本工厂,用我想要使用的精确的、不断发展的open替换open的骨架。或者,您可以在“Perl”文件夹的“Resources”目录中放置一个完成模板。按下定义的一系列键时,将使用这些完成骨架。几乎任何严肃的编辑器都会有类似的功能
使用BBEdit,您甚至可以在文本替换逻辑中使用Perl代码。我用这种方式。您可以在BBEdit中使用Template::Toolkit
,以智能方式处理宏。它可以设置为在您输出要测试或编译的版本之前,模板不会更改源代码;编辑器实质上是一个预处理器
使用文本编辑器可能存在两个问题。首先是单向/一次性转换。如果要更改“宏”的功能,则无法更改,因为“宏”的上一个文本已被使用。您必须手动更改它们。第二个潜在问题是,如果使用模板表单,则无法将源代码的宏版本发送给其他人,因为预处理是在编辑器中完成的
不要这样做强>
如果键入perl-h
以获取有效的命令开关,您可能会看到一个选项:
open my $FP, '>', $outfile or die "$outfile could not be opened for writing:$!";
诱人!是的,您可以通过C预处理器运行Perl代码,展开C风格的宏,并定义#defines
。放下枪;走开;不要这样做。存在许多平台不兼容和语言不兼容
你会遇到这样的问题:
-P run program through C preprocessor before compilation
印刷品:
#!/usr/bin/perl -P
#define BIG small
print "BIG\n";
print qq(BIG\n);
在Perl 5.12中,-p
开关已被删除
结论
这里最灵活的解决方案就是编写一个子例程。您的所有代码都在子例程中可见,易于更改,并且调用时间更短。除了代码的可读性之外,没有什么真正的缺点
Template::Toolkit被广泛使用。您可以编写类似宏的复杂替换,甚至比C宏更复杂。如果您对宏的需求值得学习,请使用Template::Toolkit
对于非常简单的情况,请在编辑器中使用单向变换
如果你真的想要C风格的宏,你可以使用。这可能与perl-P
开关具有相同的不兼容性。我不能推荐我
BIG
small
sub with_file_do(&$$) {
my ($code, $mode, $file) = @_;
open my $fp, '>', $file or die "Could not open '$file' for writing:$!";
local $FP = $fp;
$code->(); # perhaps wrap in an eval
close $fp;
}
# usage
with_file_do {
print $FP "whatever\n";
# other output things with $FP
} '>', $outfile;