More Fun with Perl and Inline IFs

Posted in: Technical Track

My old arch-nemesis, the in-line if ($q = $q == $a ? $b : $c;) reared its ugly little head again.

This time, it was in context of an web page that displayed some form values, something like this:

CGI::textfield({name  => 'price_dollars',
                        width => '5',
                        value => ($mode eq 'Edit' ? $line_item[$count]->price_dollars() : '0') });
CGI::textfield({name  => 'price_cents',
                         value => ($mode eq 'Edit' ? $line_item[$count]->price_cents(): '00' });

This carried on for 15 other fields on the form. So, we have 17 if else statements all checking to see if the form is in ‘Edit’ mode. If there were, say, ten line items on the form . . .  well no need to go any further, other than to say that is a whole lot of if statements.

While this does not take up much space, this multiplicity of ifs is not really necessary or even good, since to the compiler, an inline if and a bracketed one are the same. The inline is only a shorthand to make our code more readable.

We could of course just declare 17 scalars at each iteration, and then a use single if statment to set these scalars, like this . . .

my $price_dollars = '0';
my $price_cents = '00';
if ($mode eq 'Edit') {
    $price_dollars = $line_item[$count]->price_dollars();
    $price_cents = $line_item[$count]->price_cents();

. . . and then use them later on:

 CGI::textfield({name  => 'price_dollars',
                        width => '5',
                        value => $price_dollars}).
CGI::textfield({name  => 'price_cents',
                        value => $price_cents });

Well at least this cuts down on the if statements, but now I have a whole bunch of single-use scalars hanging about–not very neat.

I could go for an Array or a Hash for my values, but as you might have already guessed, $line_item[$count] is an object of some form. So why not just use that?

So. At each iteration I check to see if I have a invalid line item . . .

if (!$line_item[$count]) {
    $line_item[$count] = Foo::Bar:LineItem->new();

. . . and if I do, I simply create a new empty one, and then simply do this on my form:

 CGI::textfield({name  => 'price_dollars',
                        width => '5',
                        value => $line_item[$count]->price_dollars() });
 CGI::textfield({name  => 'price_cents',
                      value => $line_item[$count]->price_cents()});

Much simpler, and easier to read. Cheers!


Interested in working with John? Schedule a tech call.

No comments

Leave a Reply

Your email address will not be published. Required fields are marked *