views:

97

answers:

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>

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!

+1  A: 

Mojo uses the strict module so you must declare to use.

http://perldoc.perl.org/strict.html

Prix
+5  A: 

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

DVK
But I wonder why some of the other elements in the same file use `% %p` without error?
Nimbuz
Once it's declared once at the top of the file, its lexical scope will extend to the end of the file.
DVK
Also, the starting "%" is totally unrelated - it's merely a way for mojo to know something is a template's Perl code as opposed to HTML
DVK
+1  A: 

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.

vol7ron