Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Succinct switch statement

by jakobi (Pilgrim)
on Oct 23, 2009 at 20:30 UTC ( [id://802972]=note: print w/replies, xml ) Need Help??


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:

  • For a cleaner syntax, you can use for my $_ (@ARGV) instead of the while if your loop nevers needs to access/eat multiple array members per iteration.
    But don't attempt the parens you normally should use with local, my and our: for my($_) (@ARGV)... will fail.
  • To fall through, you can either set $_ suitably or unshift one or more values.
  • Note the structural similarity of the lines above to, say, the suggestions in the mass pattern matching thread (->qr//, closures) or dispatch table methods (e.g. removing next, saying last whileloop depending on method-rc, and assuming NOP as default method)

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 :-))

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://802972]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2024-04-20 03:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found