http://www.perlmonks.org?node_id=1073085

For some time now I've been obsessed with clean decision trees. No solution is appropriate for all needs and, as usual, tradeoffs are in play. Today I hacked out one particular way of simplifying these trees.

Here's the original mess, which usually worked but sometimes did not, and looks messy: fragile, unmaintainable. A block of code is set up for string eval:

if ( not $code ) { $code = $unit; }; if ( $args and ref $args ) { @args = @$args; $code .= q{(@args)}; } else { @args = (); }; if ( $argv and ref $argv ) { @ARGV = @$argv; }

Both $code or $args may be supplied or not; and an attempt is made to exhaust all four possible cases. As you can see, I've painted myself into such a corner that I've introduced a third input variable.

Another approach, which truly annoys me, is to nest conditionals:

if ( $A ) { if ( $B ) { {...} } else { {...} }; } else { if ( $B ) { {...} } else { {...} }; };

This is so ugly and miserable I've rarely employed it. The second evaluation of the nested comparison, whatever it may be, is particularly offensive.

Alternatively, exhaust all four cases explicitly, at the cost of introducing two scratch flags:

# Four-outcome tree my $cf = !!$code; my $af = !!( $args and ref $args ); if ( $cf && $af ) { @ARGV = @$args; } elsif ( $cf && !$af ) { @args = (); } elsif ( !$cf && $af ) { @args = @$args; $code = $unit . q{(@args)}; } elsif ( !$cf && !$af ) { @args = (); $code = $unit . q{()}; } else { die 'Fifth element!' };
  • Sets out all four cases explicitly.
  • All four cases at same level.
  • Flags guarantee simple boolean state.
  • Eliminates the wacky third input variable.

Of course tim toady; and I don't doubt others will rush to display their favorite decision trees. This one may work for me sometimes.

Death only closes a Man's Reputation, and determines it as good or bad. —Joseph Addison