neilwatson has asked for the wisdom of the Perl Monks concerning the following question:

Can someone please explain what is going on in this snippet I'm reading from the Cookbook:

%states = ( 'default' => \&front_page, 'Shirt' => \&shirt, 'Sweater' => \&sweater, ); $current_screen = param(".state") || "default"; die "No screen for $current_screen" unless states{$current_screen}; # Generate the current page. standard_header(); #how does this while loop work? while (my($screen_name, $function) = each %states) { $function->($screen_name eq $current_screen); } standard_footer(); exit; ############################# # subroutines for each screen ############################# # The default page. sub front_page { my $active = shift; return unless $active; # how do the above 2 lines work? print "<H1>Hi!</H1>\n"; print "Welcome to our Shirt Shop! Please make your selection from + "; print "the menu below.\n"; shop_menu(); } # Page to order a shirt from. sub shirt { my $active = shift; #what does this line do? my @sizes = qw(XL L M S); my @colors = qw(Black White); my ($size, $color, $count) = (param("shirt_size"), param("shirt_color"), param("shirt_count") +); ... yada yada

Thank you,

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: Explaination of syntax please
by robartes (Priest) on Oct 10, 2002 at 14:54 UTC
    Listen very closely grasshopper, for I shall say this only once (ahem). First, shift:
    my $active = shift;
    shift is a function that, well, shifts an element of an array. It takes an array argument and takes off the first element of that array, returning said element. Hang on, you say, there's no argument in the above call. Well, yes there is, grasshopper. See, in the absence of an explicit argument, most functions default to $_ or @_, which in the above context is the argument list to the function call. So the above code line is a fancy way of saying that $active will contain the first argument of the function call.

    In the code above, the functions check whether their first argument is true (i.e. a value that is not 0 and not undef):

    my $active=shift; return unless $active;
    So, unless the first argument to the function call is true, the function returns immediately. However, this is where *I* am confused, grasshopper, as your shirt function does not seem to function as the other clothes functions function (how many times a day do you get to say that?). sub shirt does not return if not $active. Whether this is intentional or not cannot be determined from the code fragment.

    Anyway, back to the lesson. We were talking about the first argument to the function calls. Were are the functions called? Well, here:

    while (my($screen_name, $function) = each %states) { $function->($screen_name eq $current_screen); }
    To understand this snippet, you first have to understand that the %states hash holds a series of screen / function entries. For each screen (default, Shirt, Sweater) there is a corresponding function reference: the function reference is the \&shirt thingy in the hash. So, this hash links screens to functions.

    Are you still with me, grasshopper, for enlightenment awaits just around the corner. The while loop will loop over all the entries of the states hash by using each and sneakily assigning the key to $screen_name and the value to $function as it goes (the cheek of some code...):

    my($screen_name, $function) = each %states
    We're almost there now. The while loop than calls the function referenced in $function using the arrow notation just to confuse you even more. Behind the arrow is the argument to the function call. This argument is the result of the comparison between $screen_name and $current_screen, which is 1, or true, if they are the same and 0, or false if not.

    And that is pretty much all there is to it. After all of this unpleasantness, only the function that corresponds to the current screen will have produced any output, which is the general goal behind this whole piece of code.

    There now grasshopper, that wasn't so bad now, was it? I hope this will help you along on the path to enlightenmnent, happiness and deeper understanding of the care and feeding of camels.

    Good reading with the rest of the Cookbook!

    CU
    Robartes-

      That was good, you should try and turn it in to a tutorial.

      jjdraco
      learning Perl one statement at a time.
Re: Explaination of syntax please
by rdfield (Priest) on Oct 10, 2002 at 14:46 UTC
    It's a CGI program that calls each function referenced in the state hash with a 1 if the name of the function is the same as what was in the parameter ".state", otherwise the function is called with a 0. The functions are coded to immediately return if supplied with a 0.

    rdfield

Re: Explaination of syntax please
by neilwatson (Priest) on Oct 10, 2002 at 15:31 UTC
    You have provided me with another stone with which to pave my path to enlightenment. Many thanks masters.

    Neil Watson
    watson-wilson.ca