Forum Webscript.Ru

Программирование => Perl => Тема начата: DDHR от 05 Мая 2004, 14:11:33

Название: Подпрограмма
Отправлено: DDHR от 05 Мая 2004, 14:11:33
Мне нужно вот этот код:

          $categories = $dbh->prepare("SELECT * FROM  WHERE type=\'news\'")
|| die "Can\'t prepare statement: $DBI::errstr";
          $categories->execute;

$end=0;

while(@row = $categories->fetchrow_array)
{

if($row[3] == $cat)
{
$end=1;
}

}

           $categories->finish;

undef @row;

if($end != 1)
{

          $categories = $dbh->prepare("SELECT * FROM categories WHERE type=\'news\'")
|| die "Can\'t prepare statement: $DBI::errstr";
          $categories->execute;

while(@row = $categories->fetchrow_array)
{

if($row[2] == $cat)
{
$p=$row[1];
$l=$row[2];
}

}

           $categories->finish;
           @names=(@names,$p);
           @cats=(@cats,$l);

}
else
{

$l=$cat;

for ($i=0; $i<10; $i++)
{
$n=0;
          $categories = $dbh->prepare("SELECT * FROM categories WHERE type=\'news\'")
|| die "Can\'t prepare statement: $DBI::errstr";
          $categories->execute;
while(@row = $categories->fetchrow_array)
{

if($n==0)
{
$n=0;
}

if($row[3]==$l)
{
$p=$row[1];
$l=$row[2];
@cats=(@cats,$row[3]);
@names=(@names,$row[4]);
$n=1;
}

}
          $categories->finish;

}
@cats=(@cats,$l);
@names=(@names,$p);
}


запихнуть в отдельный pl файл и использовать как подпрограмму (потому как этот кусок кода будит часто использоваться в дальнейшем). При вызове необходимо передать подпрограмме параметр $cat, после её выполнения получить (вернуть основной программе) два массива: @cats и @names.

PS: документацию по созданию подпрограмм читал..., вроде всё сделал верно, но помоему там что-то не то проиходило во время выбора из таблицы categories  вобщем не работало, помогите пожалуйста!

А! и вот ещё, чтобы не вводить в заблуждение: тот кусок кода абсолютно рабочий, тоесть без использования подпрограммы - он исправно работает.
Название: Подпрограмма
Отправлено: NeoNox от 05 Мая 2004, 14:17:37
Цитировать
DDHR:
документацию по созданию подпрограмм читал..., вроде всё сделал верно

покажи как ты делаеш вывод этой подпрограммы и что возвращает return.
можно без вышепреведенного кода
Название: Подпрограмма
Отправлено: DDHR от 05 Мая 2004, 16:54:40
Вот так я в основной программе вызывал подпрограмму:
require "файл";
имя подпрограммы($cat);

Вот то, что по идеи она должна возвращать:
return (@cats и @names);
Название: Подпрограмма
Отправлено: NeoNox от 05 Мая 2004, 16:58:11
Напрямую вернуть два массива у тебя не получится - они сольются в один список. Здесь нужно использовать ссылки. Вот тебе наглядный пример как это делать:
Цитировать

#!/usr/bin/perl -w
use strict;

my @a1 = (1,2,3);
my @a2 = (4,5,6);

    print "\\@a1:   @a1\\n";
    print "\\@a2:   @a2\\n";

    my ($r1,$r2) = return_me_two_arrays(\\@a1,\\@a2);

    print "\\$ r1=(",@$r1,") \\$ r2=(",@$r2,")\\n";


sub return_me_two_arrays
{
  my $ba1 = shift;
  my $ba2 = shift;
  $_++ foreach (@$ba2);
  return ($ba1,$ba2);
}

Название: Подпрограмма
Отправлено: DDHR от 05 Мая 2004, 18:14:52
То, что вы сказали - это мне пригодится, но проблема в том, что основная программа, после строчки require "../файл.pl"; она вообще ничего не показывает(не выводит на печать), а только то, что до неё!
Название: Подпрограмма
Отправлено: NeoNox от 05 Мая 2004, 18:47:14
ага понял.
твой файл.pl(тот который ты подключаеш) в самом конце должен содержать одну строчку:
Цитировать

1;

это должна быть последняя строка подключаемого скрипта.
Название: Подпрограмма
Отправлено: DDHR от 05 Мая 2004, 19:45:40
хм... сделал всё, как сказали и проблема осталась... дело в том, что в том файле, который я подключаю есть ещё подпрограммы, может это влияет на ход выполнения? или ещё что?
Название: Подпрограмма
Отправлено: NeoNox от 05 Мая 2004, 19:48:47
А ты не пробовал выводить отладочную информацию по ходу выполнения скрипта?
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 15:34:29
Так он ведь, как я сказал ничего и не выводит после строчки require "../файл.pl"; или вы про саму подпрограмму?
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 15:42:08
что значит не выводит?
завершается с ошибкой или если стоит print "Я вот здесь"; после require просто не выводится? Я надеюсь файл имеет другое имя а не на русском \'файл.pl\'? А пробовал ты указать полный путь к этому файлу?
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 15:45:34
конечно же не на русском =) файл.pl хех =)

да, то что принт, то и не выводится..., щас попоробую с полным путём...
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 15:52:35
Неа, нет, полный путь не повлиял, я его и так правильно указывал ранее... Да чтож такое та... уже пару дней бьюсь над глупой незадачей...
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 16:15:08
А если в скрипте, котрый подключается, вставить что нибудь типа кода:
open (FH, ">./debug") or warn "Can\'t open file: $!@";
print FH \'Done!\';
close FH;
будет ли создан файл с именем debug?
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 16:27:23
Да, создаётся.
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 16:59:27
Значит выводи через равные куски отладочную информацию в файл. Там где он заснет и ищи проблему.
Название: Подпрограмма
Отправлено: Alone от 06 Мая 2004, 17:03:27
попробуй так
eval "require \'файл.pl\'";
print $@;
должен вывести описание ошибки
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 17:08:21
Alone как мы уже выяснили, require у него проходит.
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 17:37:30
Я тут кое-что выяснил: файл не создаётся если это:

open (FH, ">./debug") or warn "Can\'t open file: $!@";
print FH \'Done!\';
close FH;


написать не после require..., а после вызова подпрограммы из этого модуля:

название подпрограммы($cat); # я её так вызываю (причём в цикле)

вот здесь вобщем перестаёт работать!
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 17:42:31
покажи эту подпрограмму.
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 18:00:45
sub cat($cat)
{
          $categories = $dbh->prepare("SELECT * FROM categories WHERE type=\'news\'")|| die "Can\'t prepare statement: $DBI::errstr";
          $categories->execute;

$end=0;

while(@row = $categories->fetchrow_array)
{

if($row[3] == $cat)
{
$end=1;
}

}

           $categories->finish;

undef @row;

if($end != 1)
{

          $categories = $dbh->prepare("SELECT * FROM categories WHERE type=\'news\'")|| die "Can\'t prepare statement: $DBI::errstr";
          $categories->execute;

while(@row = $categories->fetchrow_array)
{

if($row[2] == $cat)
{
$p=$row[1];
$l=$row[2];
}

}

           $categories->finish;
           @names=(@names,$p);
           @cats=(@cats,$l);

}
else
{

$l=$cat;

for ($i=0; $i<10; $i++)
{
$n=0;
          $categories = $dbh->prepare("SELECT * FROM categories WHERE type=\'news\'")|| die "Can\'t prepare statement: $DBI::errstr";
          $categories->execute;
while(@row = $categories->fetchrow_array)
{

if($n==0)
{
$n=0;
}

if($row[3]==$l)
{
$p=$row[1];
$l=$row[2];
@cats=(@cats,$row[3]);
@names=(@names,$row[4]);
$n=1;
}

}
          $categories->finish;

}
@cats=(@cats,$l);
@names=(@names,$p);
}







        @names=reverse @names;
        @cats=reverse @cats;

return (@cats);
}
1;
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 18:43:04
что вот это значит? sub cat($cat)
прочитай о прототипах и перепиши начало саба так (насколько я понял):
sub cat($)
{
$cat = $_[0];
...
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 18:56:44
Кстати, тебя использование use strict в своих скриптах как никого другого касается. Исправь это и лишишся головной боли.
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 18:57:58
Да, вы правильно поняли. Тут я ошибся с оформлением..., переделал..., изменений нет. Она (осн. программа) как-будто перестаёт работать после вызова фунции.
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 18:59:58
use strict в основной программе использую..., а в подпрограмме его тоже нужно писать?
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 19:02:18
угу. у тебя же здесь куча необьявленных данных.
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 19:09:51
пошли дальше. меняем все
|| die
на
or die
следующее, покажи основной скрипт.
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 19:13:28
ВСЁЁЁЁ! УРА!!!! и Браво! :beer:  Вот ошибка:

Я то выборку из таблицы произвожу в подпрограмме, а подключение к БД не делаю (в самой же подпрограмме, а делаю только в основной)... хех... вот поэтому и не работало!

ОГРОМНОЕ Спасибо вам лично за помощь и потраченное на меня время!
_________
PS: а подключение к БД ведь можно в отдельную подпрограмму занести и вызывать в другой подпрограмме?
Название: Подпрограмма
Отправлено: NeoNox от 06 Мая 2004, 19:15:01
да, все зависит от желания
Название: Подпрограмма
Отправлено: DDHR от 06 Мая 2004, 19:15:53
Ну, тогда тема закрыта!