My first thought on reading your node is that you somehow like to cause problems for yourself. I am forced to assume that you must not have read FamousLongAgo's link to Dominus' famous rebuttal of symbolic references. If you just missed it then go read that first. Your general approach right now is just painful and will be even more painful in the future when it breaks in strange and mysterious ways.

In general you don't have to copy all the parameter data off of the CGI object's param() list. You could just grab it directly wherever you need it. Your example number four is the best of the lot. If you didn't have that bit on "within this loop: also check for specific, or no data on each field" then you could reduce that to a subroutine. If you really feel somehow constrained from cherry-picking your expected results from param() then just use this.

sub param_hash { my $q = shift; my %param; $param{$_} = $q->param($_) for $q->param; return \ %param }

Your examples had a variety of misunderstandings and errors. I've corrected them here. Consider this another reason why you personally shouldn't be using this feature right now. I feel like a broken record here but this feature requires some significant understanding and is not for use in everyday magic.

Example number one just highlights that you didn't predeclare your variables. That's just good code hygiene. Consider this like brushing your teeth - just do it.

Example two is flawed because now you've misunderstood the difference between pad variables and global variables. Symbolic references modify globals, not lexicals. You must change your my ($varA, $varB, $varC ....) (and those are particularly poor choices for variable names) lines to use vars qw($varA $varB $varC); or our ($varA, $varB, $varC). Once you've declared your globals then you can refer to them.

Example three is incoherent. I don't know why you're using an array - perhaps for notational convenience? Anyhow, unless you plan to some hash-ify your array keys you're exchanging something nice like $cgi_param{'sort_preference'} for $cgi_param[5] which is a hell of a lot less readable. You could have previously said use constant SORT_PREFERENCE => 5; in which case it'd actually be ok (and for a few reasons also good) to say $cgi_param[SORT_PREFERENCE]. Using constants as array indexes has the benefit of giving you some compile-time typo checking so you can't inadvertantly say $cgi_param[SRRT_PREFERENCE].

You also erred in sorting your parameter list - that's a but in your implementation. If you really planned on using an array like that then you'd probably say this instead:

my @field_names = $q -> param; my @field_values = (); for my $index (0 .. $#field_names) { $field_values[$index] = $q->param( $field_names[$index] ); # within this loop: also check for specific, or no data on each f +ield }

At this point I hope it's clear to you that Best Practices indicate that you either (a) fetch the values as needed from your CGI object, (b) copy the values to a hash, or (c) copy the values to an array but use constants instead of direct array offsets. Actually best practices probably also state that you should pre-declare your expected form parameters and only operate off of those. That approach might look something like this:

# Predeclare which parameters are needed and also specify # which are expected to contain lists. All others are # expected to contain scalars. use constant EXPECTED_PARAMETERS => { sort_preference => '', signature => '', display_fields => 'ARRAY' }; # Get the CGI object my $q = CGI->new; # Get the parameters and store in a hash reference my $params = get_parameters( $q, EXPECTED_PARAMETERS ); # Do whatever the script does ..... sub get_parameters { # The first parameter is the CGI object. # The second parameter is an hash reference # to the list of expected parameters. The values # are examined for the string 'ARRAY' and those # are then retrieved into array references. my $q = shift; my $expected = shift; # Get a list of all the parameter names in a hash # This allows me to do exists() tests for parameters my %params; my @params{ $q -> params } = (); # Now go get each expected parameter my %extracted; while (my ($param_name, $param_type) = each %$expected) { # warn of missing parameters unless (exists $params{$param_name}) { cluck "Missing CGI parameter $param_name"; next; } # Copy the value over. This does a bit of fancy # footwork by extracting 'ARRAY' parameters into # arrays and all others into a plain scalar. It is # not sufficient to simply copy over values since # the behaviour for CGI's param() function changes # depending on the value of wantarray(). $extracted{$param_name} = $param_type eq 'ARRAY' ? [ $q -> param($param_name) ] : $q -> param($param_name); # Return the expected parameter list as a # hash reference. return \ %extracted }

Fun Fun Fun in the Fluffy Chair


In reply to Re: Creating variables while using 'strict' by diotalevi
in thread Creating variables while using 'strict' by nedals

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.