I have some functions that use far too many parameters, and many of the parameters are optional. So as to simplify, I'm converting a lot of them from using many params, so just using one: a hash (whose key/value pairs represent the params that used to be passed).

So, now what I have is a nice elegant API that looks like:

foo ( { param => "value", ... } );

Until I actually convert all the CALLS to the function in the new format, I've written the functions in such a way that it can accept either form by using ref() on the first param and seeing if it's a hash. If so, the function's vars are set to the has key/value pairs. otherwise, the rest of the args are read from @_.

All's well and good, and things work properly. However, for one function, there were so many params that I thought I would simplify the above process using a loop as illustrated in the code below. The surprise isn't so much to do with the parameters to the function, but the setting of the values to the local my variables within the function.

Can someone explain the scoping going on here that isn't preserving the variables' values outside of the "using args..." block?

#!/usr/bin/perl use strict; sub foo { my ( $flags, $img, $name, $big, $gallery, $page, $caption, $num ); my $opts = shift; if (ref $opts eq "HASH") { print "using hash...\n"; no strict; for (qw( flags img name big gallery page caption num ) ) { $$_ = $opts->{$_}; print "\tsetting $_ to $$_ ($opts->{$_})\n"; } use strict; } else { print "using args...\n"; $flags = $opts; # these vars are local for some reason... ??? ( $img, $name, $big, $gallery, $page, $caption, $num ) = @_; print "flags = $flags, img = $img\n"; # they're getting set... # but their values are now going to vanish... } print "reviewing what's been set...\n"; no strict; for (qw( flags img name big gallery page caption num ) ) { print "\t$_ = $$_\n"; } use strict; } # it doesn't matter which order you call these functions... foo( "hi", "apoinv", "slkjhfp", "876", "poi", "asdf", "sdf", "there" ) +; foo( { flags => "hi", img => "apoinv", name => "slkjhfp", big => "876", gallery => "poi", page => "asdf", caption => "sdf", num => "there" });


In reply to these aren't locals, but they seem to act like it by argv

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.