Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> require не работает под апачем 
V
    Опции темы
infarch
Дата 1.10.2012, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Возникла странная проблема с require. Когда из консоли выполняю тестовую функцию то все отлично. Под апачем выдает ошибку Cant locate Docia/Tools/Test/TestAAA.pm in @INC. Вот скрипт:

Код


package Docia::Tools::Test;
use strict;
use warnings;
sub some_method {
    require Docia::Tools::Test::TestAAA;
    Docia::Tools::Test::TestAAA::some_method();
}

1;



Код

package Docia::Tools::Test::TestAAA;
use strict;
use warnings;
sub some_method {
    print "Content-type: text/plain\r\n\r\nHi\n";
    return 1;
}
1;



Код


use lib ("/bb_projekt/docia/perl/lib");
Docia::Tools::Test::some_method();



Я не могу использовать use, так как сайт запускается на линуксе и под виндой. Под виндой надо подключать Win32 модули которых на линуксе нет. Поэтому я работу с ними вынес в Docia::Tools::Test::TestAAA и подключаю его через require если это винда. Но вот под апачем проблема. Помогите пожалуйста разобраться!
PM MAIL   Вверх
alezzz
Дата 1.10.2012, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 1
Всего: 14



удалил, невнимательно прочитал.

Добавлено через 4 минуты и 53 секунды
Попробуйте в use lib относительный путь указать. Где лежат модули и какой home у апача?

Это сообщение отредактировал(а) alezzz - 1.10.2012, 16:44
PM MAIL   Вверх
Logo
Дата 1.10.2012, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 694
Регистрация: 22.7.2008

Репутация: 3
Всего: 10



Возможно дело в переменной окружения PERL5LIB которую апач не передает, или в том что под апачем путь к скрипту и проету различается, насколько я знаю в винде для апача часто делают отдельный диск.
Посмотрите массив @INC, в нем лежат все пути, по которым perl ищет модули, и найдите, где ошибка.

Это сообщение отредактировал(а) Logo - 1.10.2012, 21:50
PM MAIL   Вверх
infarch
Дата 2.10.2012, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Позвольте мне вкратце описать архитектуру. Имеется апач+мод_перл. Все запросы обрабатывает controller.pl. Запрос включает в себя команду по которой определяется пакет и функция, после чего эта функция выполняется. Все скирпты расположены в папке /bb_projekt/docia/perl/lib, на которую контроллер ссылается в первой строке: use lib ("/bb_projekt/docia/perl/lib"); Тут подключаются многие модули проекта и все работает хорошо. Но вот если в каком-либо обработчике я посмотрю @INC, то в нем уже нет пути к моим библиотекам, вместо него просто точка (.)
Ну и понятно что require не может найти нужный модуль. Куда могла дется библиотека из инка? Не понимаю...
Вот краткая иллюстрация работы:

Код

# controller.pl

use lib ("/bb_projekt/docia/perl/lib");

# тут модуль подключается без проблем
use Docia::MyModule;

use CGI ();
CGI->compile(':all', ':utf8');
my $cgi=CGI->new();

my $cmd = $cgi->param('cmd');

my $subref;
eval('$subref = \&' . $command{$cmd});
$subref->($dbh,$cgi);



Далее, допустим команда обрабатывается в Docia::MyModule::func();

Код


package Docia::MyModule;

sub func {

# require тут не сработает - либа таинственно исчезла из инка
require Docia::AnotherModule;
Docia::AnotherModule::func();

}

1;


Уже и не знаю что думать (
PM MAIL   Вверх
Pfailed
Дата 2.10.2012, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



Может дело в eval? Почему бы не обойтись без него
Код

$command{$cmd}->($dbh, $cgi)



--------------------
PM MAIL   Вверх
infarch
Дата 2.10.2012, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Без eval нельзя. Там не ссылки на функции, а просто строки:

Код


    $command{'group.list'}="Docia::CGI_Group::group_list";
    $command{'group.create.form'}="Docia::CGI_Group::group_create_form";
    $command{'group.delete.form'}="Docia::CGI_Group::group_delete_form";
    $command{'group.rename.form'}="Docia::CGI_Group::group_rename_form";


PM MAIL   Вверх
Pfailed
Дата 2.10.2012, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



Просто строки тоже должны работать, во всяком случае с no strict 'refs';


--------------------
PM MAIL   Вверх
infarch
Дата 2.10.2012, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Кто же стрикт отключает? Не вариант.
PM MAIL   Вверх
Pfailed
Дата 2.10.2012, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



При необходимости все отключают. Никто ведь не заставляет отключать его во всём скрипте, обычно это делают так
Код

use strict;
...
{
    no strict 'refs';
    $subname_as_str->($a,$b,$c);
}
...

В любом случае стоит проверить решает ли это проблему.



--------------------
PM MAIL   Вверх
Logo
Дата 2.10.2012, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 694
Регистрация: 22.7.2008

Репутация: 3
Всего: 10



eval не нужен
Код

my $subref = \&{$command{$cmd}};
$subref->($dbh,$cgi);

Либо так, как описал Pfailed.

Цитата

Тут подключаются многие модули проекта и все работает хорошо. Но вот если в каком-либо обработчике я посмотрю @INC, то в нем уже нет пути к моим библиотекам, вместо него просто точка (.)

Точка означает рабочую директорию

Код

Куда могла дется библиотека из инка? Не понимаю...

Странно...  Посмотрите, где изменяется значение @INC. С помощью команды отладчика w или модулей вроде Tie::Watch, Tie::Trace.
PM MAIL   Вверх
infarch
Дата 3.10.2012, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Logo, ваш вариант работает. Действительно, можно обойтись без eval. Это само по себе хорошо, никогда его не любил. Но вот в работе require это ничего не изменило. Инк дальше теряет либу.

Так что я пошел другим путем, и таки опять через eval: eval "require Win32" в контроллере.
По крайней мере это не убивает сервер под линуксом и помогает под виндой. 

Но я нашел куда прописать либу чтоб она была постоянно доступна. Это startup.pl который запускается через PerlRequire "c:/mod-perl/Apache2/conf/startup.pl" в perl.conf который в свою очередь прописан в конфиге апача:

<IfModule mod_perl.c>
    Include conf/perl.conf
</IfModule>

Когда я добавил туда библиотеку, INC стал таким как надо. Но... в продукции мне править глобальные настройки вебсерверов не дадут без крайней необходимости. Так что буду жить с eval'ным костылем.

Спасибо за содействие, закрываю тему.
PM MAIL   Вверх
Logo
Дата 3.10.2012, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 694
Регистрация: 22.7.2008

Репутация: 3
Всего: 10



Я и не говорил, что это поможет от изменения @INC в программе:)

Цитата

Так что я пошел другим путем, и таки опять через eval: eval "require Win32" в контроллере.
По крайней мере это не убивает сервер под линуксом и помогает под виндой. 


Когда заранее известен код, который нужно выполнить, используйте блочный eval
Код

eval {
  require Win32;
};

Это работает быстрее (не нужно заново вызвать компилятор) и помогает от ошибок компиляции в eval блоке.
PM MAIL   Вверх
infarch
Дата 4.10.2012, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Цитата(Logo @  3.10.2012,  23:58 Найти цитируемый пост)
Это работает быстрее (не нужно заново вызвать компилятор) и помогает от ошибок компиляции в eval блоке. 


Спасибо за подсказку!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1163 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.