Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
This is not a rant, but instead mantra. Nested if-else statements should be avoided!

Impossible you say? It is true that not all problems can avoid a mess of nested if-else blocks, but, with the help of Perl's syntax and use of hashes as lookup (or dispatch) tables, you might be suprised at how much your code could be cleaned up.

<update> Ovid made me realize that another important decision to make about using nested if-else blocks or avoiding them is to determine which style produces the least redundant code. </update>

Caveat - don't get caught up in Premature optimization - meeting all the specification requirements is much more important. But then again, somebody is going to have to maintain it. If you are interested in job security through obscurity then this node is not for you. ;)

Consider this object method that accepts either a scalar argument or an array reference (of course, most other languages require you provide two seperate methods):

sub foo { my ($self,$ref) = @_; if (ref $ref eq 'ARRAY') { if ($#$ref) { # do case number 1 } else { # do case number 2 } } else { # do case number 2 } }
I have to determine if the user passed an array reference or a scalar no matter what. But, in this case i also want to know how many elements were passed in an array reference, because if they pass only one element, then that really should be the same as passing a scalar. (Also note that i am not checking to make sure $ref is not undef or is a another kind of reference - keepin it simple.)

The problem is that i can't just test for $#$ref, because that will cause a syntax error under strict if $ref is a scalar. So, i have to use another if-else block inside the block for the case of an array reference. Yuck. And on top of that, i am repeating a whole code block. Super yuck.

However, if i make sure that $ref is indeed an array reference even if it isn't, then i can condense this down to two blocks:

sub foo { my ($self,$ref) = @_; $ref = [$ref] unless ref $ref eq 'ARRAY'; if ($#$ref) { # do case number 1 } else { # do case number 2 } }
Now, there is more than one way to condense the original problem, this is just one. I am not necessarily looking for other ways to solve this problem.

The reason i post this meditation is because i am interested in what others have done to condense and refactor if-elsif-else blocks for simplicity. And using Switch doesn't count! ;) But using dispatch tables definitely does.

P.S. In school i studied Karnough maps which are used to simplify circuit design. Turns out that conditionals (if (this or that and not the other) {}) are not at all different and K-Maps can be used to simply them. Very neat stuff.

jeffa

L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
F--F--F--F--F--F--F--F--
(the triplet paradiddle)

In reply to Why I Hate Nested If-Else blocks by jeffa

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others having an uproarious good time at the Monastery: (4)
    As of 2014-09-21 21:49 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (176 votes), past polls