Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > require


Автор: rcdimon 25.6.2005, 20:10
Я хочу огромную программу раскидать по отдельным файлам. Хочу в разные файлы впихнуть сходные по функциям подпрограммы. Но почему то не все работает.


Вот это код основной программы
Код

#!/usr/bin/perl
use CGI qw(:all);
    

print header( -charset => 'Windows-1251' );

require 'db.cgi';

my $sql= "df";

print db($sql);



А это код того файла, который подсоединяется в главном

Код

#!/usr/bin/perl


use DBI;    



#    Принимает строковую переменную $sql


sub db {


    $a = $sql;
    return ("$a");


}



Так вот ничего не работает. А если я соединяю просто в один файл, то все ОК. ПОчему? Помогите, пожалуйста!

Автор: korob2001 25.6.2005, 22:06
В конец каждого подгружаемого файла добавь единицу и удали первую строку, она не нужна:
Код

use DBI;    

sub db { return shift };

1;

Удачи.

Автор: TwiSteR 26.6.2005, 00:00
korob2001

Че-то у меня тоже не получается, даже 1 (конец) указываю, не работает smile

Автор: korob2001 26.6.2005, 07:56
Вот эти два файла сохрани в один тот же каталог:
файл first.pl
Код

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

my $num = 10;
my $res = 0;

no strict;
require 'second.pl';
$res = sqr( $num );
use strict;

print $res;

файл second.pl
Код

sub sqr {
    my $num = shift;
    $num *= $num;
    return $num;
}
1;

Запусти файл first.pl в результате, на выходе увидишь число которое указано в переменной $num в квадрате.
Удачи.

Автор: sharq 26.6.2005, 13:02
rcdimon лучше всего использовать не require, а use, т.е. используй модульное программирование. Так будет работать на много быстрее и это правильный подход к программированию.
Создавай модули и у тя проблем не будет. smile

Автор: sharq 26.6.2005, 13:32
Вот пример:
Модуль Tools.pm
Код
#sharq
package Tools;

use strict;
use DBI;

#
# ФУНКЦИИ ДЛЯ РАБОТЫ С БАЗОЙ ДАННОЙ  
#                                        
# функция подключения к БД с логином и паролем
sub connect() {

    my $dsn = "DBI:mysql:host=$HOST_DB;database=$NAME_DB";    
    my $dbh = DBI->connect( $dsn, $USER_DB, $PASS_DB,  { PrintError => 0,  RaiseError => 1,  AutoCommit => 0 });         
    return $dbh;
}

...

1;


Основной скрипт index.cgi
Код
#!perl 
#sharq
                                     
use strict;
use warnings;
use diagnostics;
use CGI qw(-no_xhtml);
use CGI::Carp qw(fatalsToBrowser);

use Tools;

$CGI::POST_MAX = 1024 * 100;  # max 100K posts
$CGI::DISABLE_UPLOADS = 1;  # no uploads

enable diagnostics;

my $dbh = Tools::connect();

...

$dbh->disconnect();

exit(0);


Только index.cgi и Tools.pm должны лежать в одной директории. Вот и все!

ЗЫ раньше я тоже все делал через require, но это не практично, ресурсоемко и получается, что ты просто вставляешь в скрипт кусок подключаемого файла.
И я перешел на модули. Скорость реально увеличилась и стал заметен стиль программирования.
Понятное дело, я не желею. smile

smile

Автор: korob2001 26.6.2005, 15:12
А я давно перешёл на классы. Правда require и use не одно и тоже. Если у тебя етсть большой файл, кторый разбит на много подпрограмм, которые выполняются в зависимости от действий пользователя. Допустим в одной из всех подпрограмм, тебе нужно подгрузить другой файл, то гораздо лучше использовать require, так как use не спрячешь от компилятора, даже если он будет внутри подпрограммы, т.е. модуль будет загружен даже если эта подпрограмма и не запускалась.

Автор: sharq 26.6.2005, 17:40
korob2001
Цитата
Правда require и use не одно и тоже
если это было одним и тем же, это называлось бы одним и тем же словом smile
Вопрос: зачем писать большие-большие скрипты, в которых легко запутаться и трудно отладить?
Поэтому и пишут модули, в которых есть ряд функций, выполняющие опред. действия, их легко отладить и модифицировать, и несколько скриптов, которые используют те или иные модули.

Хотя каждый делает так, как ему удобно. smile

Автор: rcdimon 26.6.2005, 19:48
А как использовать use то?

Автор: korob2001 26.6.2005, 21:43
Цитата

если это было одним и тем же, это называлось бы одним и тем же словом

Вот так, это одно и тоже:
Код

BEGIN { require 'myfile.pl' };

Цитата

Вопрос: зачем писать большие-большие скрипты, в которых легко запутаться и трудно отладить?

Лично мне гораздо проще и, главное, быстрее отладить один большой скрипт, чем много маленьких. А если уж разбивать на модули, то здесь я предпочитаю ООП. Хотя не могу с тобой не согласиться, каждый в праве писать так, как ему удобно. smile
Цитата

А как использовать use то?

Сначала пишешь модуль или класс, сохраняешь его в файл с рассширением .pm, имя должно соответствовать имени пакета. Затем кидаешь его в библиотечный каталог, если удоступа к такому каталогу у тебя нет, значит создаёшь отдельный каталог, и в каждом скрипте, который будет использовать твой модуль или класс, прописываешь такую строку:
Код

use lib qw( путь/к/библиотечному/каталогу );
# здесь подключаешь модуль
use Имя::Модуля;

Ну вот собственно и всё. Хотя если пишешь модуль не забудь об экспорте, если класс, не забудь о конструкторе.

Если хочешь пример, то вот здесь можешь почитать о том, как создаются классы:
http://forum.vingrad.ru/index.php?showtopic=43392
а здесь увидеть, как примерно пишется модуль:
http://forum.vingrad.ru/index.php?showtopic=55677

Если возникнут конкретные вопросы, пиши.

Автор: sharq 27.6.2005, 09:58
korob2001
Цитата
А если уж разбивать на модули, то здесь я предпочитаю ООП.

Да, согласен, есть ряд задач, когдалучше использовать объекты, но не всегда.

Код

use lib qw( путь/к/библиотечному/каталогу );

Это, конечно, хорошо, но крайне неудобно при переносе скрипта, каждый раз менять...
imho, лучше модули хранить в той же директории, что и скрипт, подключающий их или, на крайняк, импортировать модуль в вызвавший пакет.

Например, есть основной скрипт проекта index.cgi и директория MyModule, в которой находятся несколько модулей, которые используются в скрипте, например - MySub.pm.
MySub.pm
Код
package MyModule::MySub;    
use strict;
no strict 'refs';
...
# Экспортирует все функции в вызвавший пакет.
# Вызывается автоматически.
sub import {

    while( my ( $k, $v ) = each( %{ __PACKAGE__."::" } ) ) {
        next if substr( $k , -1 ) eq ":" || grep { $k eq $_ } qw(BEGIN import);
             *{ caller()."::".$k } = $v;
    }
}

1;


Тогда index.cgi подключает такие модули как обычные модули:
Код
#!perl                        
use strict;
use  MyModule::MySub;
...


Давно нашет такое решение на http://dklab.ru. Впредь им пользуюсь.

Цитата
если пишешь модуль не забудь об экспорте

это не обязательно...

Автор: korob2001 27.6.2005, 18:54
Цитата

это не обязательно...

Но желательно. smile Что бы не обращаться к подпрограмме так: MyModule::myfunc();

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)