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.
精彩评论