Разница между "% p" и "моим% p"? - PullRequest
3 голосов
/ 03 июля 2010
% %p = ('option1' => 'Option 1', 
% 'option2' => 'Option 2', 
% 'option3' => 'Option 3'
% );
    <select name="killer_feature" id="killer_feature" class="select">
% foreach (keys %p) {
% my $selected = param('killer_feature') && param('killer_feature') eq $_ ? 'selected="selected"' : '';
% if (!param('killer_feature') && $_ eq 'option2') { $selected = 'selected="selected"' }
    <option value=" <%=$_%>" <%= $selected %>>
        <%= $p{$_} %>
    </option>
% }
    </select>

приведенный выше код ломает приложение, возвращая «Внутренняя ошибка сервера», но если я просто отредактирую самую первую строку на % my %p (я пробовал, потому что некоторые другие элементы управления имеют этот формат), это работает, интересно, какая разница между двумя.

Это Perl-приложение, созданное на веб-платформе Mojolicious.

Большое спасибо!

Ответы [ 2 ]

8 голосов
/ 03 июля 2010

Raw %p говорит об использовании глобальной (пакетной) переменной "% p". Чтобы быть более техническим, по умолчанию необъявленное имя переменной считается переменной пакета и незаметно добавляется к имени текущего пакета - например, это действительно будет относиться к переменной %main::p, так как по умолчанию вы находитесь в основном пакете.

НО Если Perl-код запускается интерпретатором с включенной прагмой use strict (как и в случае с mojo), это автоматическое предварительное ожидание имени текущего пакета для не объявленных переменных не произойдет, и поэтому код с такой переменной не будет компилироваться, поскольку переменная %p фактически не известна ни из лексического объявления области видимости, ни из таблицы символов пакета.

Добавление my объявляет переменную "% p" в локальную (лексическую) область видимости, и теперь она с радостью удовлетворит прагму strict.

Более подробное (и лучше написанное) объяснение области видимости переменных в Perl можно найти на веб-сайте Рэндала Шварца по консультациям Stonehendge: http://www.stonehenge.com/merlyn/UnixReview/col46.html

2 голосов
/ 03 июля 2010

Похоже, ваш настоящий вопрос: что такое ключевое слово my и зачем оно нужно?

my используется для объявления переменной в локальной области, а также локально для подпрограммы:

#!/usr/bin/perl

use strict;

   my $foo = "defined in outer";
   print_result ("outer",$foo);             # outer: defined in outer

   {
      # $foo has not yet been defined locally
      print_result ("inner",$foo);          # inner: defined in outer

      my $foo = "defined in inner";         # defining $foo locally

      print_result ("inner",$foo);          # inner: defined in inner 

      my $foo;                              # re-declaring $foo

      print_result ("inner", $foo);         # inner:  
   } 

   # even though $foo was defined in the subroutine, it did not
   # override the $foo outside the subroutine (localization occured)
   print_result ("outer",$foo);             # main: defined in main      


   sub print_result {
      my ($proc,$value) = @_;
      print qq{$proc:\t$value\n};
   }

Поскольку Mojolicious использует use strict, он требует, чтобы все переменные были объявлены с помощью (my, our, local и т. Д.).

Обратите внимание, что происходит, когда вы используете my более одного раза в коде выше. Это излишне повторно объявляет переменную, перезаписывая то, что было ранее назначено.

Как и в большинстве языков программирования, вам нужно объявить переменную только один раз, а затем снова использовать эту переменную при необходимости.

...