在perl中eval和print之间的冲突

时间:2014-08-14 21:20:10

标签: regex perl printing eval

我正在我的perl脚本中创建一个子程序,可以很好地评估它并且它可以工作。我还想打印子程序的内容以进行调试。然而,在code中构造的子程序非常庞大,只需打印就很难阅读和理解它。我想找到一种能够以半缩进方式打印它的方法。

这是code代的一部分:

$code .= "if (\$ct=~/^\\s*\$/x  || \$Im < \$Ix) {push(\@min, $b); push(\@max, $b);} if (\$Im > \$Ix) {push(\@min, $a); push(\@max, $a);}"

我想打印出类似这样的内容:

if (\$ct=~/^\\s*\$/x  || \$Im < \$Ix) 
    {push(\@min, $b); push(\@max, $b);}
if (\$Im > \$Ix)
    {push(\@min, $a); push(\@max, $a);}

我知道执行此操作的直接方法是编写另一个脚本来解析它,并将一些\n\t放入code中的相应位置,然后将其打印出来。我想知道是否有更聪明的方法呢?就像把\n放在code的某个地方,而不是颠覆eval它。 (即print可见但eval不可见的东西)。

注意:我的子程序中有很多正则表达式,我希望每次都避免运行它们。这就是为什么我需要将代码存储在字符串中然后eval来增加我的脚本性能。

PS这显然是因为我的懒惰!

1 个答案:

答案 0 :(得分:2)

忽略您可能在字符串中包含代码的原因......

Perl::Tidy是您重新格式化代码所需的工具。

通常,通过源文件上的命令行使用此工具。但是,我已经将一个小脚本一起攻击,该脚本会将您的代码字符串输出到一个临时文件,以便可以重新格式化。请注意,这当前假设您的代码格式正确,并且其中没有任何明显的语法错误,因为格式化代码不在此工具的范围内。

use strict;
use warnings;
use autodie;

my $code = <<'END_CODE';
# It hurts to write ugly code, but I'll see what I can do
sub { my @vars = @_;
 my $count = scalar(@vars); print "Hello World.  Vars = $count"; return; }
END_CODE

print pretty_code($code);

sub pretty_code {
    my $code = shift;

    require File::Temp;
    require Perl::Tidy;

    my ($fh, $filename) = File::Temp::tempfile();
    print $fh $code;
    close $fh;

    Perl::Tidy::perltidy(
        source => $filename,
    );

    my $output = do {
        open my $fh, '<', "$filename.tdy";
        local $/;
        <$fh>
    };

    unlink $_ for ($filename, "$filename.tdy");

    return $output;
}

输出:

# It hurts to write ugly code, but I'll see what I can do
sub {
    my @vars  = @_;
    my $count = scalar(@vars);
    print "Hello World.  Vars = $count";
    return;
  }

<强>更新

不需要使用临时文件,尤其是Perl::Tidy在将其转储到磁盘之前在内存中累积整理的代码。如果您愿意,该程序可以在不将结果写入磁盘的情况下执行相同的操作。

use strict;
use warnings;

use Perl::Tidy 'perltidy';

my $code = <<'END_CODE';
# It hurts to write ugly code, but I'll see what I can do
sub { my @vars = @_; my $count = scalar(@vars); print "Hello World.  Vars = $count"; return; }
END_CODE

print pretty_code($code);

sub pretty_code {
   my ($code) = @_;
   my $pretty;

   perltidy(
      source      => \$code,
      destination => \$pretty,
   );

   $pretty;
}

<强>输出

# It hurts to write ugly code, but I'll see what I can do
sub {
  my @vars  = @_;
  my $count = scalar(@vars);
  print "Hello World.  Vars = $count";
  return;
    }

目前我不清楚为什么闭合支撑进一步缩进,但我确信结果比原来更好。