in reply to these aren't locals, but they seem to act like it

You might like to consider accessing the parameters using the hash. When you start using Perl's OO features you will find that that is standard technique anyway. Consider:

use strict; use warnings; foo( "hi", "apoinv", "slkjhfp", "876", "poi", "asdf", "sdf", "there" ) +; print "\n"; foo( { flags => "hi", img => "apoinv", name => "slkjhfp", big => "876", gallery => "poi", page => "asdf", caption => "sdf", num => "there" }); sub foo { my %args; if (ref $_[0] eq "HASH") { %args = %{$_[0]}; } else { @args{qw(flags img name big gallery page caption num)} = @_; } print "$_:\t$args{$_}\n" for sort keys %args; }

Prints:

big: 876 caption: sdf flags: hi gallery: poi img: apoinv name: slkjhfp num: there page: asdf big: 876 caption: sdf flags: hi gallery: poi img: apoinv name: slkjhfp num: there page: asdf

DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^2: these aren't locals, but they seem to act like it
by argv (Pilgrim) on Mar 12, 2007 at 15:27 UTC

    I love your solution:

    my %args; if (ref $_[0] eq "HASH") { %args = %{$_[0]}; } else { @args{qw(flags img name big gallery page caption num)} = @_; }

    But one of the things I left out so as to keep the code concise was the use of default values to apply to the locals in the even the caller didn't pass them in. This is why I used the looping mechanism that I did. Rather than specifying each line precisely, which worked, I wrote a loop for brevity and attempted elegance. The solution above is what the doctor (or grandfather) ordered. So, let's revisit my other original objective again and replace what i took out:

    $defaults = { flags => 0x8001, img => "/path/file.jpg", ... }; for (qw( flags img name big gallery page caption num ) ) { $$_ = $opts->{$_} || $defaults->{$_}; }

    We know why this doesn't work now, but how can I apply defaults from a default hash for those values not passed in using the new method (to me) shown above?

      consider:
      my %args = ( flags => 0x8001, img => "/path/file.jpg", ... ); if (ref $_[0] eq 'HASH') { @args{keys %{ $_[0] }} = values %{ $_[0] }; } else { for (qw( flags img name big gallery page caption num )) { $args{$_} = shift if @_; } }
      If you want the defaults to apply whether the parameters are passed by name or not, after you have initialized parameters from the values passed in to your sub you could simply say something like this (untested):
      foreach my $k (keys %args) { if (!defined($args{$k})) { $args{$k} = $defaults->{$k}; } }