in reply to Succinct switch statement

CONDITION and ACTION;

E.g the code I've used for ages for flexible switch parsing, as the original simple arg handling module went against my tastes:

# maybe replace @ARGV below with my(@A)=@ARGV or similar, as we destro +y the array while($_=$ARGV[0]){ /^(-V|-?-verbose)$/o and do{shift; $verbose=1; ...; next}; /^(-v|-?-negate)$/o and do{shift; $negate=1; ...; next}; ... /^--?$/o and do{shift; ...; last}; # early + loop exit last; }
cu & HTH, Peter -- hints may be untested unless stated otherwise; use with caution & understanding.

Update 1:

Considering Bloodnok's variant below:

If your Perl's sufficiently recent, use my($_) instead of local to protect your caller while also protecting from anything called functions might do.

Also note that I'm using both next and last (loop exit condition) above. If you want a stronger distinction between looping and switching while retaining early loop exiting, you need either a second target label before the while() or set an explicit loop-exit flag variable for testing after the switch block. Simply saying last SWITCH in case of -- when restructuring does introduce a bug and changes semantics of -- to a NOP, with additional problems further down the line for non-option args.

Footnotes to my example above:

Non-famous last words: I simply prefer the above solution over given/when and if-cascades for readability and perceived elegance. But given the ascii art readjustment and byte counts, it's not faster to maintain nor that much shorter.

Replies are listed 'Best First'.
Re^2: Succinct switch statement
by Bloodnok (Vicar) on Oct 23, 2009 at 23:32 UTC
    Whilst your code self-evidently works, it doesn't satisfy the general case (pun intended) since it will only work within a loop - with modifications, it can be made to work anywhere.

    The modifications involves the enclosing of the condiitons and actions inside a labelled block and reworking the next statements e.g.

    while ($_ = $ARGV[0]) { SWITCH: { /^(-V|-?-verbose)$/o and do{shift; $verbose=1; ...; last SWITCH +}; /^(-v|-?-negate)$/o and do{shift; $negate=1; ...; last SWITCH +}; ... /^--?$/o and do{shift; ...; last SWITCH +}; } }
    Also, personally, I would rewrite it as follows
    PARSE: while (@ARGV) { local $_ = shift; SWITCH: { /^(-V|-?-verbose)$/o and do { $verbose=1; ...; last SWITCH }; /^(-v|-?-negate)$/o and do { $negate=1; ...; last SWITCH }; ... /^--?$/o and do { ...; last PARSE }; } }
    Update:

    Added correct loop termination (using PARSE label) for specific instance offered above.

    A user level that continues to overstate my experience :-))