如何在Perl中的不同子例程中写入相同的文件?

时间:2010-03-21 10:55:58

标签: perl

我在使用Perl将数据写入文件时遇到了一些问题。

    sub startNewOrder{
    my $name = makeUniqueFileName();
    open (ORDER, ">$name.txt") or die "can't open file: $!\n";
    format ORDER_TOP = 
    PRODUCT<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<CODE<<<<<<<<AANTAL<<<<EENHEIDSPRIJS<<<<<<TOTAAL<<<<<<<
.
    format ORDER =
    @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<< @<<<< @<<<<<< @<<<<<
    $title,                              $code,    $amount, $price, $total
.
    close (ORDER);
}

这是我用来制作文件的子。 (我翻译了大部分内容。) makeUniqueFileName方法根据当前时间(“minuteshoursdayOrder”)生成fileName。 现在的问题是我必须在另一个子文件中写入此文件。

sub addToOrder{
print "give productcode:";
$code = <STDIN>;
chop $code;
print "Give amount:";
$amount = <STDIN>;
chop $amount;
if($inventory{$code} eq undef){ #Does the product exist?
    print "This product does not exist";
}elsif($inventory{$code}[2] < $amount && !defined($inventaris{$code}[2]) ){ #Is there enough in the inventory?
    print "There is not enough in stock"
}else{
    $inventory{$code}[2] -= $amount;
    #write in order file
    open (ORDER ">>$naam.txt") or die "can't open file: $!\n";
    $title = $inventory{$code}[0];
    $code = $code;
    $amount = $inventory{$code}[2];
    $price = $inventory{$code}[1];
    $total = $inventory{$code}[1];
    write;
    close(ORDER);
}

%inventory是一个散列表,其产品代码为key,数组的标题,价格和金额为值。 这里有两个问题: 当我输入无效的产品编号时,我仍然需要输入金额,即使我的代码说它应该在检查是否有带有给定代码的产品后直接打印错误。

第二个问题是写作似乎不起作用。它始终给出“没​​有这样的文件或目录”错误。有没有办法打开我在第一个子程序中创建的ORDER文件而不必使$name不是本地的?或者只是一种写入此文件的方法?我真的不知道如何从这里开始。我真的找不到关于编写之前已经关闭的文件以及不同子文件的更多信息。

感谢任何帮助,

危害

2 个答案:

答案 0 :(得分:4)

首先应将这些行添加到代码中:

use strict;
use warnings;

他们会发现潜在的拼写错误。例如,$inventaris是与$inventory不同的变量。你真的想要有两个变量吗?你的代码很难说清楚。同样,你真的有一个名为$naam的变量吗?

是的,可以从2个独立的潜艇写入文件。目前,$namestartNewOrder子的本地版本。使其他子可见的一种方法是在代码的开头声明它,使其成为代码文件的全局。您可以将format移动到与write相同的子徽标吗?

在您的代码中,使用chomp代替chop更合适。

最好使用exists检查是否存在哈希密钥,而不是将其与undef返回的值进行比较。

use strict;
use warnings;

my $name = makeUniqueFileName();

# Sample data
my %inventory = (
    c1 => [ 1 .. 3 ],
    c2 => [ 4 .. 6 ]
);

addToOrder();

sub addToOrder { 
    print "give productcode:\n"; 
    my $code = <STDIN>; 
    chomp $code; 
    print "Give amount:\n"; 
    my $amount = <STDIN>;
    chomp $amount;
    if (not exists $inventory{$code}) {
        print "This product does not exist\n"; 
    }
    # etc...
}

我意识到我没有回答你所有的问题。也许您可以一次关注一个问题,并提供一个包含少量实际数据样本的自包含,可运行的示例。我经常通过将代码减少到最小的例子来解决我自己的问题,这个例子仍然可以重现问题。

答案 1 :(得分:2)

子程序应该尽可能少地工作并保持尽可能小的范围。在您的情况下,您不希望必须在每个子例程中打开文件。打开文件一次并传递打开的文件句柄。您不必每次都关闭并重新打开文件。

由于您要使用格式,因此必须使用裸字文件句柄:

 my $name = makeUniqueFileName();
 open ORDER, '>', $name or die ...;

 start_new_order( \*ORDER );
 add_to_order( \*ORDER );

 sub start_new_order {
      local *ORDER = shift;
      ...
      write ORDER;
      }

 sub add_to_order {
      local *ORDER = shift;
      ...
      write ORDER;
      }

您可以在任何地方定义格式。您不必在子例程中定义它们,因此只需将它们放在文件的末尾。