Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

( [id://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":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2024-04-19 06:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found