Как я могу записать в один и тот же файл в разных подпрограммах в Perl? - PullRequest
1 голос
/ 21 марта 2010

У меня проблемы с записью данных в файл с использованием 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 создает fileName на основе текущего времени (minuteshoursdayOrder). Теперь проблема в том, что я должен написать в этот файл в другой подпрограмме.

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 - это хеш-таблица с ключом продукта и массивом с названием, ценой и суммой в качестве значения. Здесь есть две проблемы: когда я ввожу недопустимый номер продукта, мне все равно придется вводить сумму, даже если мой код говорит, что он должен напечатать ошибку непосредственно после проверки, существует ли продукт с данным кодом.

Вторая проблема заключается в том, что письмо не работает. Это всегда выдает ошибку «Нет такого файла или каталога». Есть ли способ открыть файл ORDER, который я сделал в первом сабвуфере, без необходимости делать $name не локальным? Или просто способ записи в этот файл? Я действительно не знаю, как начать здесь. Я не могу найти много информации о записи файла, который был закрыт ранее, и в другой подпрограмме.

Любая помощь приветствуется,

Вред

Ответы [ 2 ]

4 голосов
/ 21 марта 2010

Вы должны начать с добавления этих строк в свой код:

use strict;
use warnings;

Они поймают потенциальных опечаток. Например, $inventaris - это переменная, отличная от $inventory. Вы действительно хотели иметь две переменные? Трудно сказать по вашему коду. Точно так же у вас действительно есть переменная с именем $naam?

Да, запись в файл возможна из двух отдельных подпрограмм. В настоящее время $name является локальным по отношению к вашему startNewOrder sub. Один из способов сделать его видимым для другой подпрограммы - объявить его в начале кода, сделав его глобальным для вашего файла кода. Можете ли вы переместить ваш format в тот же сабвуфер, что и ваш write?

В вашем коде более целесообразно использовать chomp вместо chop .

Лучше проверить наличие хеш-ключа, используя существующие , чем сравнить его со значением, возвращаемым 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 голосов
/ 22 марта 2010

Подпрограммы должны выполнять как можно меньше работы и сохранять как можно меньший объем.В вашем случае вам не нужно открывать файл в каждой подпрограмме.Откройте файл один раз и обведите открытый дескриптор файла.Вам не нужно закрывать и заново открывать файл каждый раз.

Поскольку вы хотите использовать форматы, вы должны использовать дескрипторы файлов без слов:

 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;
      }

Вы можете определить свои форматыв любом месте.Вам не нужно определять их в подпрограмме, поэтому просто поместите их в конец файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...