Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Perl编写宏_Perl_Macros - Fatal编程技术网

用Perl编写宏

用Perl编写宏,perl,macros,Perl,Macros,我的代码中多次出现这种语句 我想对所有这些语句保持相同的格式,这样当某些内容被更改时,它只在一个地方被更改 在Perl中,我应该如何着手解决这种情况 我应该使用宏还是函数 我见过这么多这样的线程,但它并没有说明如何编写一个像 open $FP, '>', $outfile or die $outfile." Cannot open file for writing\n"; Perl 5实际上没有宏(有源代码过滤器,但它们既危险又难看,甚至我都不会将您链接到文档)。函数可能是正确的选择,

我的代码中多次出现这种语句

  • 我想对所有这些语句保持相同的格式,这样当某些内容被更改时,它只在一个地方被更改

  • 在Perl中,我应该如何着手解决这种情况

  • 我应该使用宏还是函数

  • 我见过这么多这样的线程,但它并没有说明如何编写一个像

    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;