> Dear Sean, > > Hash Slice (only reminded of this the other day). Example code: > > use strict; > use warnings; > > my @first = 'A' .. 'Z'; > my @second = 'a' .. 'z'; > > my %hash; > @[EMAIL PROTECTED] = @second; > > use Data::Dumper; > print Dumper(\%hash); > > __END__ > > Not a particularly "beginner" way to do it though. >
I was *JUST* lecturing my student on hash-slices Monday ... Part of that lecture.... Passing named paramters, implemented as a hash, is a popular style. Look at all of Perl/Tk, for example. For systems where you might pass dozens of parameters to a method (or subroutine), and you want each of those values to have reasonable defaults, you really can't beat it. An example : #!/usr/bin/perl use strict; use warnings; sub frobitz { my (%opt) = @_ ; $opt{name} = 'blueberry' unless exists($opt{name}); $opt{color} = 'blue' unless exists($opt{color}); $opt{texture} = 'medium' unless exists($opt{texture}); $opt{price} = 30 unless exists($opt{price}); # ... do something useful } frobitz ( name => 'banana', color => 'yellow', texture => 'soft', price => 5 ); Now, seeing four nearly identical lines in a row in frobitz() should make you think "There must be a better way..." How 'bout: our %frobitz_default = ( name => 'blueberry', color => 'blue', texture => 'medium', price => 30 ); sub frobitz { my (%opt) = @_ ; foreach my $key (keys %frobitz_default ){ $opt{$key} = $frobitz_default{$key} unless exists $opt{$key} } # ... do something useful... } This makes adding new default values a lot easier, you just have to edit the defaults hash. If the package global frightens you, you can make it lexically scoped to sub frobitz() at a cost of about 20% in performance. Now, a common challenge when maintaining code, is you might need to call some existing function that uses positional parameters, so you need to suck out a handful of your named parameters in a specific order.... sub update_price { my ($name, $price) = @_ ; warn "Setting $name to $price"; # udpate the price of this fruit in the database ... return ; } sub frobitz { my (%opt) = @_ ; foreach my $key (keys %frobitz_default ){ $opt{$key} = $frobitz_default{$key} unless exists $opt{$key} } update_price ( $opt{name}, $opt{price} ); # ... do something useful... } Here, we've added a line to call update_price with two positional parameters ($name, $price). If you have only two parameters, you're better off typing it out -- but what if you had something with many positional parameters - all of those $opt{}s are going to make the code very unreadable ... Hash slice to the rescue sub frobitz { my (%opt) = @_ ; foreach my $key (keys %default_frobitz ){ $opt{$key} = $default_frobitz{$key} unless exists $opt{$key} } update_price( @opt{qw /name price / } ); } The notation for hash slices is a little confusing... It is generally of the form %hash = ( .... ) ; @values = @[EMAIL PROTECTED]; (As opposed to an array slice which looks like) @values = @[EMAIL PROTECTED]; I elected to use the qw// quote-like-operator to generate a list of words (and THAT , class, is why embedded blanks in hash keys for positional parameters is a Bad Idea - because you can't use qw//) So, if instead of two parameters I had to pass a handful of parameters: some_graphic_function ( @opt{ qw / x_position y_position radius line_style color depth / } ); You can see where the Hash Slice really pays off. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Lawrence Statton - [EMAIL PROTECTED] s/aba/c/g Computer software consists of only two components: ones and zeros, in roughly equal proportions. All that is required is to sort them into the correct order. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>