开发者

Difference between '%p' and 'my %p'?

% %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{$_} %>
    </opt开发者_运维问答ion>
% }
    </select>

the above code breaks the app by returning 'Internal server error', but if I smiply edit the very first line to % my %p (I tried it because some other controls have this format) it works, I wonder whats the difference between the two.

Its a perl app built on Mojolicious web framework.

Many thanks!


Raw %p says to use a global (package) variable "%p". To be more technical, by default, a non-declared variable name is considered to be a package variable and is silently pre-pended with the name of the current package - e.g. it would be really referring to %main::p variable since you're in the main package by default.

BUT If the Perl code is run by the interpreter with the use strict pragma enabled (as it is with mojo), this automatic pre-pending of a current package name to un-declared variables does not happen, and therefore the code with such a variable will not compile as the variable %p is not actually known from either a lexical scope declaration or package symbol table.

Adding my declares the "%p" variable into a local (lexical) scope and it will now happily satisfy the strict pragma.

A much more in-depth (and better written) explanation of variable scoping in Perl is avialable from Randal Schwartz's Stonehendge consulting web site: http://www.stonehenge.com/merlyn/UnixReview/col46.html


It seems like your real question is: what is the my keyword and why is it needed?

my is used to declare the variable in the local scope and also locally to a subroutine:

#!/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};
   }

Because Mojolicious uses the use strict it requires all variables to be declared with (my, our, local, etc).

Notice what happens when you use my more than once in the code above. It unnecessarily redeclares the variable, overwriting what was previously assigned.

Like most programming languages, you only need to declare a variable once and then use that variable over again as necessary.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜