【问题标题】:How can I write to the same file in different subroutines in Perl?如何在 Perl 的不同子例程中写入同一个文件?
【发布时间】:2010-03-21 10:55:57
【问题描述】:

我在使用 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”)生成文件名。 现在的问题是我必须在另一个 sub 中写入这个文件。

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 是一个哈希表,其中 productcode 为 key,数组为 title、price 和 amount 作为 value。 这里有两个问题: 当我输入一个无效的产品编号时,我仍然需要输入一个金额,即使我的代码说它应该在检查是否存在具有给定代码的产品后直接打印错误。

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

感谢任何帮助,

伤害

【问题讨论】:

    标签: perl


    【解决方案1】:

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

    use strict;
    use warnings;
    

    他们会发现潜在的错别字。例如,$inventaris 是与 $inventory 不同的变量。你真的是想有两个变量吗?很难从您的代码中分辨出来。同样,你真的有一个名为$naam的变量吗?

    是的,可以从 2 个单独的子目录写入文件。目前,$name 是您的 startNewOrder 子本地的。使其对您的其他子可见的一种方法是在代码的开头声明它,使其对您的代码文件是全局的。你能把你的format 移动到你的write 的同一个sub 中吗?

    在您的代码中,使用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...
    }
    

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

    【讨论】:

      【解决方案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;
            }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 2019-10-13
        • 1970-01-01
        • 1970-01-01
        • 2013-01-17
        • 1970-01-01
        • 2014-09-20
        相关资源
        最近更新 更多