3
% %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(我尝试过,因为其他一些控件具有这种格式)它可以工作,我想知道两者之间有什么区别。

它是一个基于 Mojolicious Web 框架的 perl 应用程序。

非常感谢!

4

2 回答 2

8

Raw%p说要使用全局(包)变量“%p”。更技术性地说,默认情况下,未声明的变量名称被认为是包变量,并且默认以当前包的名称作为前缀 - 例如,它实际上是指%main::p变量,因为您在 main默认打包。

但是,如果 Perl 代码由use strict启用了 pragma 的解释器运行(就像使用 mojo 一样),则不会发生将当前包名称自动附加到未声明的变量的情况,因此具有此类变量的代码将不编译,因为变量%p实际上不是从词法范围声明或包符号表中知道的。

添加my将“%p”变量声明到本地(词法)范围内,它现在将很高兴地满足strictpragma。

可以从 Randal Schwartz 的 Stonehendge 咨询网站获得对 Perl 中变量作用域的更深入(并且写得更好)的解释:http: //www.stonehenge.com/merlyn/UnixReview/col46.html

于 2010-07-03T03:18:48.783 回答
2

看来您真正的问题是:关键字是什么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在上面的代码中多次使用时会发生什么。它不必要地重新声明了变量,覆盖了之前分配的内容。

与大多数编程语言一样,您只需声明一次变量,然后根据需要再次使用该变量。

于 2010-07-03T14:05:30.763 回答