perl – 如何在我加载的模块中使用Smart :: Comments而不更改其源代码?

前端之家收集整理的这篇文章主要介绍了perl – 如何在我加载的模块中使用Smart :: Comments而不更改其源代码?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何为我的原始脚本以及它直接加载的任何模块指定Smart :: Comments.但是,由于它是一个源过滤器,如果应用于每个其他加载模块加载的每个模块,它可能会造成严重破坏.

例如,我的脚本包括

use Neu::Image;

我想为Neu :: Image加载Smart::Comments,但是指定

$perl -MSmart::Comments script.pl

不为Neu :: Image加载Smart :: Comments.

此行为在Smart::Comments documentation中描述:

If you’re debugging an application you
can also invoke it with the module
from the command-line:

06002

Of course,this only enables smart
comments in the application file
itself,not in any modules that the
application loads.

我已经看过的一些其他事情:

> Perl Command-Line Options
> perldoc perlrun(我搜查了一下
对于“模块”这个词)

替代方法
正如gbacon所提到的,Smart :: Comments提供了一个环境变量选项,允许打开或关闭它.但是,如果可能的话,我希望能够在不修改原始源的情况下打开它.

解决方法

您几乎肯定希望通过适当设置$Smart_Comments将Smart :: Comments添加到包含此类的模块,然后添加 flip the switch in your environment.

藏匿,进口劫持猴子修补是疯狂的.

但也许你会遇到那种事情.假设你有Foo.pm:

package Foo;

use Exporter 'import';
our @EXPORT = qw/ foo /;

#use Smart::Comments;

sub foo {
  my @result;
  for (my $i = 0; $i < 5; $i++) {
    ### $i
    push @result => $i if $i % 2 == 0;
  }
  wantarray ? @result : \@result;
}

1;

普通用法

$perl -MFoo -e 'print foo,"\n"'
024

当然,平凡无聊乏味.有了run-foo,我们采取大胆,潇洒的步骤!

#! /usr/bin/perl

use warnings;
use strict;

BEGIN {
  unshift @INC => \&inject_smart_comments;

  my %direct;
  open my $fh,"<",$0 or die "$0: open: $!";
  while (<$fh>) {
    ++$direct{$1} if /^\s*use\s+([A-Z][:\w]*)/;
  }
  close $fh;

  sub inject_smart_comments {
    my(undef,$path) = @_;
    s/[\/\\]/::/g,s/\.pm$// for my $mod = $path;
    if ($direct{$mod}) {
      open my $fh,$path or die "$0: open $path: $!";
      return sub {
        return 0 unless defined($_ = <$fh>);
        s{^(\s*package\s+[A-Z][:\w]*\s*;\s*)$}
         {$1 use Smart::Comments;\n};
        return 1;
      };
    }
  }
}

use Foo;

print foo,"\n";

(请原谅紧凑性:我缩小它所以它将适合未展开的块.)

输出

$./run-foo

### $i: 0

### $i: 1

### $i: 2

### $i: 3

### $i: 4
024

¡万岁!

使用@INC hooks,我们可以替换自己的或修改过的来源.该代码监视尝试要求程序直接使用的模块.在命中时,inject_smart_comments返回一个迭代器,一次产生一行.当这个狡猾的,巧妙的迭代器看到包声明时,它会向块中添加一个看起来无辜的Smart :: Comments,使它看起来好像它一直在模块的源代码中.

通过尝试使用正则表达式解析Perl代码,例如,如果包声明本身不在一行上,则代码将中断.品尝季节.

原文链接:https://www.f2er.com/Perl/171820.html

猜你在找的Perl相关文章