perl - 用 Perl 编写报告

标签 perl format

我正在尝试使用 perl 写出多个报告文件。每个文件具有相同的结构,但具有不同的数据。所以,我的基本代码看起来像

#begin code
our $log_fh;
open %log_fh, ">" . $logfile

our $rep;

if (multipleReports)
{
   while (@reports) {
     printReport($report[0]);
   }
}

sub printReports
{
   open $rep, ">" . $[0];
   printHeaders();
   printBody();
   close $rep;
}

sub printHeader() {
format HDR =
@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$generatedLine
.

format HDR_TOP =
.

$rep->format_name("HDR");
$rep->format_top_name("HDR_TOP");

$generatedLine = "test";
write($rep);
$generatedLine = "next item";
write($rep);
$generatedLine = "last header item";
write($rep);
}

sub printBody #There are multiple such sections in my code. For simplicity, I have just shown 1 here
{
 #declare own header and header top. Set report to use these and print items to $rep
}

#end code

以上只是我正在使用的代码的概要,我希望我已经掌握了所有要点。但是,由于某种原因,我得到了正确输出的第一个报告文件。第二个文件而不是第一部分

测试
下一项
最后一项

阅读

最后一项
最后一项
最后一项

我已经尝试了很多主要围绕自动刷新的选项,但是,对于我的生活来说,我无法弄清楚为什么这样做。我正在使用 Perl 5.8.2。非常感谢任何帮助/指点。

谢谢 乔治

编辑 1 我尝试将文件句柄作为参数传递给子例程,但问题仍然存在。 然后,我将格式语句移到子例程之外,并将 $generated 变量声明为全局变量。这似乎解决了它。我认为出于某种原因每次都声明格式,子程序被调用,似乎把它搞砸了。不确定到底是为什么。 奇怪的是,我将格式语句移回子例程内部(我不喜欢将所有格式语句中的所有变量声明为全局变量的想法)。但是,这次我将声明更改为

my $generatedLine = "";
my $format = "format HDR = \n" .
'@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' . "\n" .
'$generatedLine' . "\n" .
'.';

my $formatTop = "format HDR_TOP = \n".
'.';

   eval $format;
   eval $formatTop;

这似乎也有效 - 我在我的多个文件中看到了正确的输出(好吧..我目前只测试 2 个文件..我明天会做更多的测试)。

知道为什么以这种方式声明格式似乎有效吗? eval 有什么特别之处吗?

谢谢 乔治

最佳答案

我从来没有用过,但是Text::Report如果您正在制作复杂的报告,看起来很有希望。

关于更一般的问题,您的代码让我认为您没有使用 use strictuse warnings 运行。如果没有,请打开它们。这将提供许多线索。

此外,您似乎在使用子例程,这很好,但没有利用它们的主要目的之一——即为变量范围提供明确定义的区域。例如,为什么 $rep 需要是一个全局变量?如果子例程需要一些信息,请将其作为参数传入。尤其是当您的程序试图一遍又一遍地执行相同的任务时——例如生成一堆报告——您需要注意不要让一次迭代中的变量在后续迭代中保留陈旧的值。

在您的程序组织中执行一些基本纪律将在很大程度上解决此类问题。这是一个简单的例子。

use strict;
use warnings;

# Example usage: perl script.pl foo.txt bar.txt
main(@ARGV);

sub main {
    my @report_names = @_;
    for my $rep_name (@report_names) {
        my @fake_data = map rand(), 1..10;
        printReport($rep_name, @fake_data);
    }
}

sub printReport {
    my ($rep_name, @data) = @_;
    open my $fh, ">", $rep_name or die $!;
    printHeader($fh);
    printBody($fh, @data);
    close $fh;
}

sub printHeader() {
    my $fh = shift;
    print $fh "Header\n";
}

sub printBody {
    my ($fh, @data) = @_;
    print $fh "Body\n";
    print $fh $_, "\n" for @data;
}

关于perl - 用 Perl 编写报告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2877531/

相关文章:

xml - 使用 libXML/XPath 提取和存储 XML 数据

windows - 用于创建简单 Microsoft Windows GUI 的 Perl 模块?

perl - 带有散列和可选标量参数的子例程

cocoa - token 字段的可拖动元素,如 Mac 时钟格式面板

node.js - IBM WebSphere/MQTT.js : Convert MQHRF2 to MQSTR format

asp.net - 在 Windows Shell 中转义传递给 perl 脚本的参数

string - Pentaho 将字符串转换为带小数点的整数

python - 如何格式化 float 以千位、反点和逗号分隔?

java - 使用 JPA 属性日历的日期格式问题

Excel::Writer::XLSX 内容不可读错误