2009-08-03 3 views
9

Привет, Я использую Perl-скрипт, написанный другим человеком, которого больше нет в компании. Если я запустил скрипт как самостоятельный, то вывод будет таким, как ожидалось. Но когда я вызываю скрипт из другого кода несколько раз, вывод ошибочен, за исключением первого раза.Как я могу принудительно выгрузить модуль Perl?

Я подозреваю, что некоторые переменные не инициализированы должным образом. Когда он называется автономным, каждый раз, когда он выходит, и все значения переменных инициализируются значениями по умолчанию. Но при вызове из другого скрипта perl модули и значения переменных, вероятно, переносятся на следующий вызов сценария.
Есть ли способ сбросить вызванный сценарий из памяти, прежде чем я его вызову в следующий раз?

Я пробовал включить предупреждение, и он выдавил 1000 строк предупреждений ...!

EDIT: Как я звоню другой сценарий:

код выглядит следующим образом:

do "processing.pl"; 
... 
... 
... 

process(params); #A function in processing.pl 
... 
... 
... 
+1

Как вы называете этот другой скрипт? – innaM

+0

См. Редактирование. Дайте мне знать, если это не ясно. – Manoj

ответ

4

Если вы не хотите переписывать/исправить скрипт, я предлагаю позвонить сценарию через exec() или один из его вариантов. Хотя это не очень элегантно, это определенно поможет решить вашу проблему.

+1

Как это устранить проблему? Вы думаете о том, чтобы развернуть обработку, а затем выполнить? –

+2

Проблема с использованием «exec» заключается в том, что вы не можете вызвать функцию «process», потому что она не была загружена в программу. Таким образом, вам придется беспокоиться о том, как вернуть информацию из программы exec'd в формате, которым может управлять Perl. Я предполагаю, что какой-то отформатированный вывод, который сгенерировал строку, которая, когда eval'd, инициализировала переменную, могла бы работать - но проще было бы просто продолжить очистку или переписывание кода. –

11

Если вы хотите, чтобы заставить модуль перезагружается, удалите его запись из %INC, а затем перезагрузить Это.

Например:

sub reload_module { 
    delete $INC{'Your/Silly/Module.pm'}; 
    require Your::Silly::Module; 
    Your::Silly::Module->import; 
} 

Обратите внимание, что если этот модуль основан на глобалов в другие модули создаются, те, возможно, потребуется перезагрузка, а также. Нет простого способа узнать, не принимая пика в коде.

+2

Module :: Reload будет обрабатывать эти детали для вас, но также обратите внимание на мой комментарий к ответу tsee. –

+0

@Brian: действительно ли модуль: перезагрузите проблему, которую не поддерживает модуль :: Unload? Неужели? –

0

Другая возможность (просто вслух здесь) может быть связана с локальным каталогом? Они бегут с одного и того же места. Вероятно, в первый раз это не сработало.

Другой вариант - использовать system ('doprocessing.pl');. Ленько мы делаем это с помощью нескольких сценариев, чтобы принудительно повторно инициализировать несколько классов/переменных и т. Д. И заставить файлы журналов правильно вращаться.

Редактировать: Я только что перечитал ваш вопрос, и, похоже, вы не называете это так.

5

Выгрузка модуля является более сложной задачей, чем просто удаление входа% INC модуля. Взгляните на Class::Unload от CPAN.

+7

Обратите внимание, что Class :: Unload не является прямым решением этой проблемы. Цель состоит в том, чтобы очистить что-либо внутри конкретного пакета. Это не отменяет ничего, что мог бы сделать модуль, например, возиться с специальными переменными Perl, определять что-либо в других классах (что-то, что я часто делаю), или любые другие вещи, которые может сделать модуль, который не включает символ Таблица. –

+0

Вы правы, конечно. Хотя я и помнил, что в документах Class :: Unload был раздел CAVEAT, но я ошибся. – tsee

8

Привет Я использую Perl-скрипт, написанный другим человеком, которого больше нет в компании. Я попытался включить предупреждение, и он забрасывал 1000 строк предупреждений ...!

У вас есть проблемы с этим. Сценарий не был написан правильно и должен быть переписан.

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

Я бы не стал доверять запущенному с ошибкой скрипту, написанному кем-то уже не с компанией. Я бы переписал его и был уверен, что он делает то, что мне нужно для этого.

+1

Даже если нет предупреждений, вы все равно не знаете, правильно ли это делает. Предупреждения меняются с версиями Perl, поэтому вы не можете сделать вывод, что вы просто получаете множество предупреждений. –

+2

Я бы вывел неаккуратную кодовую базу, которая должна быть приоритетной для перезаписи :) Но согласился, что отсутствие предупреждений не свидетельствует об отсутствии ошибок. – Ether

3

Вы уверены, что вам нужно перезагрузить модуль? Используя do, вы каждый раз читаете источник и выполняете его. Что произойдет, если вы измените это на require, который будет только читать и оценивать источник один раз?

Смежные вопросы