Seems like you are doing it the hard way, but my way might be harder in a different way. I'd first write something to enumerate the different possibilities. (method varies, but like a "pick (3,5)" -- a random example I wrote in my perlish shell style):
#!/bin/bash -u include stdalias sub errmsg () { my code=1 if (($#>1)) ; then code=$2 fi echo "Error: $1" exit $code } # call with "parmnum <wanted>" - checks wanted against actual alias parmnum='_parmnum $# ' sub _parmnum () { int expected=${1:-0-1} actual=$2 if ((expected!=actual)) ; then echo "Incorrect param count($actual). Expected $expected." exit 1 fi return 0 } sub permute () { # ( inArName outArName) #: randomly permute in->out +) parmnum 2 my snam="$1" dnam="$2" readarray -t "$dnam"< <(printf "%s\n" $( eval "echo \${$snam[@]}") | sort --random-sort +) } sub pick () { #(parms: #params inArray_name outArray_name) parmnum 3 int savecnt=$1 cnt=$1 my snam="$2" dnam="$3" set "" $(eval echo '${'$snam'[@]}' ) shift if (($#<cnt)); then printf "Cannot pick %s from list of len %s\n" "$cnt" "$#" exit 1 fi eval "$dnam=()" while ((0 < cnt--));do eval "$dnam+=( \"$1\" )" shift || return 1 done eval "$snam=( $(echo \"$@\") )" if (($(eval "echo \${#$dnam[@]}")<$savecnt)); then return 1 fi return 0 } sub dropcaches () { echo -n "3"|sudo dd of=/proc/sys/vm/drop_caches } # runall |& tee -a /tmp/ndd.log if [[ $# -ge 2 ]]; then array in=( $(echo "$@") ) array out array mypick permute in out else array in=( $(echo {1..8} ) ) array out array mypick permute in out fi readarray -t ops< <(printf "%s\n" ''{,--nmmap} ) int dflt=8 int apt=2 #args/test int args=$# int nargs=$[args?args:dflt] int nops=${#ops[@]} if ((nops*apt>nargs)) ; then { printf "%s: Too few args for %s tests @ %s/test\n" \ "$nargs" "$nops" "$apt" exit 1 } >&2 fi if [[ ! $0 =~ bash ]]; then echo Drop Caches... dropcaches echo Start tests for op in "${ops[@]}"; do pick 2 out mypick cmd=$(echo "ndedup $op ${mypick[@]}" ) echo "$cmd" time $cmd || exit $? done fi
I didn't want the caches used in the same order each time to prevent disk locality from coming into play.... So basically permute & pick # vals from list.

then for each test (this one tried 2 "ops" with and without "--nmmap")

For more perlish work, I'd rewrite those in perl -- should be trivial.

Then for execution, I would use either a hash or look through an array of cases, depending on howmuch control I needed over ordering. The thing is, the hash or array can be created on the fly, so you don't need to do the coding of the if/else cases... They can be run automatically after you put in the cases to test.

Example of the ARRAY case to choose a format, with tests in order:

my $fmt; # prototypes are documentary (rt#89053) my $given = [ sub ($$) { $_[0] =~ /^[-+]?[0-9]+\.?\z/ && q{% +s} }, sub ($$) { $_[1] && qq{ +%s}}, sub ($$) { 1 == length($_[0]) && q{' +%s'}}, sub ($$) { $_[0] =~ m{^(?:[+-]?(?:\.[0-9]+) | (?:[0-9]+\.[0-9]+))\z}x && q{ +%.2f}}, sub ($$) { substr($_[0],0,5) eq 'HASH(' && '{'.sw(ellipsis).'}' +}, sub ($$) { substr($_[0],0,6) eq 'ARRAY(' && '['.sw(ellipsis).']' +}, # sub ($$) { $mxstr && length ($_[0])>$mxstr # && qq("%.${mxstr}s")}, sub ($$) { 1 && q{" +%s"}} ]; do { $fmt = $_->($v, $ro) and last } for @$given; return sprintf $fmt, $v;
And a hash case, (this time creating a format for refs):
no strict 'refs'; my %actions = ( GLOB => ($p->{implicit_io}? *IO_glob: *NIO_glob), IO => ($p->{implicit_io}? *IO_io : *NIO_io), REF => sub(){ "\\" . $p->Px($$_, $lvl-1) . ' '}, SCALAR=> sub(){ $pkg.'\\' . $p->Px($$_, $lvl).' ' }, ARRAY => sub(){ $pkg."[". (join ', ', map{ $p->Px($_, $lvl) } @$v ) ."]" + }, HASH => sub(){ $pkg.'{' . ( join ', ', @{[ map {$p->Px($_, $lvl, 1) . '=>'. $p->Px($v->{$_}, +$lvl,0)} sort nonrefs_b4_refs keys %$v]} ) . '}' },); if (my $act=$actions{$ref}) { &$act } else { return "$v" }
You start using tables for decision trees, and it can simplify things.

A third case... is using a sub or RE to match on, and calling the action based on that. With results from the first sub or RE being used as params in the action...

I've been trying to eliminate all the features that are experimental from all my code since 5.18 . What a pointless exercise to have used them in the first place -- but I thought that they were only experimental for the 1st main release they were in, not "forever"...geez.


In reply to Re^2: Case Exhaustion Tree by perl-diddler
in thread Case Exhaustion Tree by Xiong

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!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • 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, details, 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, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            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.