> 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>


Reply via email to