2012-10-23 5 views
6

Я использую apache mod_cgi в течение нескольких лет. Теперь я перехожу к mod_perl, и я нашел некоторые проблемы, особенно с подпрограммами. До сих пор я никогда не использовал my, our или local; и скрипты CGI работали без проблем. После чтения документации и даже некоторых предыдущих вопросов, размещенных здесь, я понимаю более или менее то, как работают my, our и local. Моя забота заключается в том, какая информация будет делиться между следующими запросами (если я правильно понимаю, это основная проблема, которую я должен иметь при запуске mod_perl вместо mod_cgi).Переход от CGI к mod_perl. Понимание моего, нашего, местного

  • Есть ли разница между использованием our в скалярной или просто скаляр, не объявляя ничего особенного, таких как my? Не являются ли глобальными?
  • Если я не объявляю, что скаляр как частный будет использоваться в следующем запросе? Даже в другом запросе другого скрипта perl на том же сервере?
  • Как я могу поделиться значением скаляра внутри подпрограммы вне этой подпрограммы, но не за пределами того же файла или того же запроса?
  • Если я использую my в скаляре внутри if на том же уровне файла или в той же подпрограмме, а затем создаю еще один if, где я использую тот же скаляр; что скаляр, разделяемый между if или каждый if означает разные блоки? Что относительно while и for, являются ли они разными блоками для ранее объявленного сканера my или который работает только для подпрограмм и файлов?
+4

, если только вы не должны взаимодействовать с кишками Apache, если вы просто хотите, чтобы ускорить процесс, рассмотреть пропуская mod_perl и перейти непосредственно к [Plack] (https: // metacpan.org/module/Plack) и FastCGI. mod_perl связывает вас с Apache, раздувает весь HTTP-процесс и может утечка памяти. Многие веб-фреймворки Perl плавно работают с Plack. Однако у него есть аналогичные проблемы с глобальными и лексическими переменными, поэтому ваш вопрос остается актуальным. – Schwern

+0

@ Zillo: вы пошли очень тихо. Получите ли один из этих ответов то, что вам нужно знать? – Borodin

+0

@Schwern Я пытался запустить FastCGI на Lighttpd, но настроить его было непросто.Я использую FastCGI для PHP на Lighttpd, но, похоже, сложнее установить FastCGI для обработки скриптов Perl. – Zillo

ответ

8

Редактировать: Это общая информация о переменных переменных Perl. Пожалуйста, см. Сообщение Бородина для конкретных вопросов mod_perl.

Переменные, объявленные my, являются лексическими. Другими словами, они существуют только в пределах текущего объема. Вы должны объявить все свои переменные с my по умолчанию; только делайте что-то еще, когда вы специально хотите разную функциональность.

Использование лексико-переменных переменных является основной составляющей хорошего кода в (почти) любом языке. Помещение use strict; и use warnings; во все ваши скрипты потребует от вас соблюдения этой хорошей практики.

our - способ объявления глобальной переменной; основной результат очень похож на использование незаявленных глобалов. Однако это имеет два отличия:

  1. Вы явно заявляете, что хотите, чтобы переменная была глобальной. Это хорошая практика, так как использование глобальных переменных должно быть исключительным случаем. Из-за этого вы можете создать глобальный таким образом, даже если вы use strict;.
  2. Переменная, объявленная our, будет доступна по имени, которое вы объявляете на всех пакетах в текущей области. Необъявленная переменная, напротив, доступна только по простому имени в текущем пакете. Кроме того, вы можете ссылаться только на него как $package::variable.

Для получения более подробной информации см. the documentation for our.

local не создает лексическую переменную; вместо этого это способ дать глобальной переменной временное значение в текущей области. Он в основном используется со специальными встроенными (пунктуационных) переменных в Perl:

{ 
    local $/; #make the record separator undefined in this scope only. 
    my $file = <FILE>; #read in an entire file at once. 
} 

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

+1

Это не учитывает очень различную среду, наложенную * mod \ _perl * – Borodin

+0

@Borodin, oops, это был надзор. Я прочитал этот вопрос, так как не понял, как работает базовый обзор в Perl, и забыл о части 'mod_perl'. – dan1111

+0

Полезное объяснение общих категорий переменных Perl тем не менее – Borodin

17

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

Обычно это знание поможет многое понять изменения в окружающей среде от mod_cgi, но так как вы никогда не добавил use strict в своих программах и ознакомиться с работой объявленных переменных у вас есть много догоняющего делать !

mod_perl среды имеет потенциал для вызывая неочевидные нарушения безопасности, и вы должны начать сейчас use strict на каждый сценарий и объявить каждую переменных. use Carp также поможет вам понять журналы ошибок.

Имя переменной, объявленное our, является синонимом лексической области для переменной пакета с тем же именем, которая может быть использована без полного определения имени путем включения имени пакета. Например, обычно переменная, объявленная с our $var, обеспечит доступ к скаляру $main::var (если ранее не было объявления package) без указания main::. Однако такие переменные, которые начали жизнь с значения undef в mod_cgi, теперь сохраняют свои значения из предыдущего выполнения любого заданного потока mod_perl, и для согласованности наиболее безопасно всегда инициализировать их в точке объявления. Также обратите внимание, что имя пакета по умолчанию больше не main из-за обертывания, которое mod_perl делает, поэтому вы больше не можете обращаться к переменным пакета с помощью префикса main::, и неразумно найти фактическое имя пакета и явно использовать это потому что это будет очень длинное имя и изменится, если вы переместите или переименуете свой скрипт.

A my переменная является той, которая существует независимо от таблицы символов пакета, и обычно ее время жизни - это время выполнения прилагаемого файла (для переменных, объявленных в области файла) или подпрограммы. Они безопасны в mod_perl, если оба объявлены и используются в области содержимого сценария или полностью в рамках одной подпрограммы, но вы можете быть ужалены, если вы смешиваете области и объявляете my $global в области файлов, а затем пытаетесь использовать их в подпрограмме. Причина этого не проста, но она вызвана mod_perl, обертывая ваш скрипт в подпрограмме handler, поэтому у вас есть вложенные объявления подпрограмм. Внутренняя подпрограмма будет иметь тенденцию принимать только первый экземпляр $global и игнорировать любые другие, созданные более поздними вызовами до handler. Если вам нужна глобальная переменная, вы должны объявить ее с помощью our и инициализировать ее в этой декларации, как описано выше.

Переменная переменная очень похожа на переменную our, поскольку она образует синоним переменной пакета. Однако он временно сохраняет текущее значение этой переменной и предоставляет новую копию для использования до конца области или области блока. Из-за его автоматического создания и удаления в пределах своей области применения он может быть полезной альтернативой переменной my в сценариях mod_perl, особенно если вы используете указатели на структуры данных, такие как, например, экземпляр класса CGI. Объявление our $cgi = CGI->new правильно создало бы объект, но из-за mod_perl's persistence оставил бы его в памяти, пока следующее выполнение потока не удалит его, чтобы освободить место для другого.

Что касается ваших вопросов:

  • Использование переменной без объявления либо вызывает ошибку компиляции, если use strict на месте, как это должно быть. В противном случае это синоним этой переменной в текущем пространстве имен пакетов.

  • Переменные - это либо переменные пакета, либо лексические переменные; нет способа объявить переменную как private как таковой. Лексические переменные (объявленные с my) будут созданы и уничтожены при каждом выполнении сценария, если вы не создали недопустимое закрытие , как описано выше, написав подпрограмму, которая использует переменную, объявленную в более широкой области, когда переменная будет но не будет делать то, что вы хотите. Переменная, объявленная с our, сохранит свое значение во всех вызовах сценария, а объявленный с помощью local будет уничтожен при завершении сценария. Обе переменные our и local являются переменными пакета, и все ссылки на одно и то же имя переменной относятся к одной и той же переменной.

  • Чтобы объявить переменную, которая постоянно доступна везде, в любом вызове скрипта, вы можете использовать переменную local или инициализированную переменную our. В области файлов local $global в значительной степени эквивалентен our $global = undef для mod_perl скриптов. Если вы используете переменную our, чтобы указать на структуру данных, то не забудьте уничтожить ее в конце скрипта с помощью undef $global.

  • my переменные являются уникальными для, и видимые внутри, блока, в котором они были объявлены, независимо от того, что представляет собой блок в пределах if, while или for, или даже просто голой { ... } блок-области. Всегда используйте переменные my для временных рабочих переменных, которые используются только внутри блока и доступны из ниоткуда.

Я надеюсь, что это помогает

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

  • Нет связанных вопросов^_^