【问题标题】:Difference between '%p' and 'my %p'?“%p”和“我的%p”之间的区别?
【发布时间】:2011-03-11 08:32:06
【问题描述】:
% %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 网络框架的 perl 应用程序。

非常感谢!

【问题讨论】:

    标签: perl mojo mojolicious


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 但是我想知道为什么同一个文件中的其他一些元素使用% %p没有错误?
    • 一旦在文件顶部声明一次,其词法范围将延伸到文件末尾。
    • 另外,开头的“%”是完全不相关的——它只是 mojo 了解模板的 Perl 代码而不是 HTML 的一种方式
    【解决方案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,它要求所有变量都用(myourlocal 等)声明。

    注意当您在上面的代码中多次使用my 时会发生什么。它不必要地重新声明了变量,覆盖了之前分配的内容。

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

    【讨论】:

      猜你喜欢
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 2011-03-07
      • 1970-01-01
      相关资源
      最近更新 更多