Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Wednesday September 11, 2002
03:56 PM

do {} saves time and money

[ #7681 ]

One physicist told me that all computer programs are simply a series of if statements. He also controlled most of a very large (football field size) medium-energy nuclear physics apparatus from a Mac Classic, fancy pictures and all, so I was not going to debate "all".

At the moment I work for another scientific application which really is a series of if-statements. It has about 30 inputs, and depending on their combined values, several other values need to be set. The convoluted conditions resist refactoring.

        my( $setting1, $setting2 );
        if( $param1 > 5 and $param2 > 8 )
                $setting1 = 4;
        elsif( $param1 > 6 and $param3 > 9 )
                $setting1 = 5;
                $setting2 = 9;
        elsif( ... ) { ... }

To write this sort of code I have to type $setting1 several time---in each block that wants to set it and in the initial my() statement. It looks sort of like a switch statement, but really is not since some conditions depend on multiple parameters (that may be different parameters for each condition ). The problem is not the structure, really, just the repitition. Furthermore, I really do not like using my() without immediately assigning meaningful values.

When I started this project a year ago, I fell in love with do {}. The return value of block sorts of things is the last evaluated expression in the block. If the block contains only a if-elsif-else structure, the last evaluated expression is the last expression in the followed branch. If I make the last evaluated expression a list of values, I can easily assign to many variables at the same time and only have to type their name once.

        my( $setting1, $setting2 ) = do {
                if ( $param1 > 5 and $param2 > 8 ) { ( 4, ) }
                elsif( $param1 > 6 and $param3 > 9 ) { ( 5, 9 ) }
                elsif( ... ) { ... }

This little trick reduces the line count of some fo the code I am refactoring by four or five times. I can see an entire if-elsif-else tree on the screen, and with proper whitespace adjustments, I can easily compare inputs and outputs. The structure is mostly the same, but the assignment is different, and much cleaner.