Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
I have reworked the construct as discussed earlier. I include a minimal test suite here to demonstrate the expected behavior.
#!perl use strict; use warnings; use Test::More tests => 13; use Case; my $case = Case::switch( 'foo' => sub {5} ); ok($case, 'create switch'); is($case->('foo'), 5, 'found'); is($case->('bar'), undef, 'default default'); $case = Case::switch( Case::default => sub { 'given' } ); is($case->('foo'), 'given', 'supplied default'); $case = Case::switch( qw(foo bar baz) => sub {'fell thru'}, Case::default => sub {'too far'} ); is($case->('foo'), 'fell thru', 'normal fall-thru'); $case = Case::switch( qw(foo bar) => sub {'one ' . $Case::action->('baz')}, sorbet => sub {'to cleanse the palate'}, baz => sub {'chain'} ); is($case->('foo'), 'one chain', 'chaining'); $case = Case::switch( qw(foo bar) => sub {"got $_"}, qw(baz) => sub {$Case::action->('foo')}, 'roy' => sub { 'special '. $Case::action->('foo')}, Case::default => sub { 'Just wasting space' } ); is($case->('foo'), 'got foo', 'arg is $_'); is($case->('baz'), 'got baz', 'arg is $_ when chained'); is($case->('roy'), 'special got roy', 'cat chained return'); # Weird ones ok(Case::switch(), 'completely empty'); ok(Case::switch(sub{}), 'default only'); ok(Case::switch('foo'), 'term, no sub'); diag("Should get a malformed switch warning"); ok(Case::switch(sub{}, sub{}), 'malformed switch warning');
and the module itself, which is more lightweight and (I think) elegant than before:
package Case; use Carp; use Exporter; @ISA=(Exporter); @EXPORT_OK=qw(switch default); use strict; use warnings; sub default {} sub switch { my %swash; my $default = \&default; my $code; my $assigned_code; # Handle degenerate case return $default if (@_ == 0); # Handle default if ((ref $_[-1]) eq 'CODE' and (@_ ==1 or ref $_[-2] eq 'CODE')) { $default = pop(@_); } for my $item (reverse @_) { if ((my $reftype = ref $item) eq 'CODE') { carp "Malformed switch: action with no terms" if $code and ! $assigned_code; $code = $item; $assigned_code = 0; } elsif ($reftype) { croak "switch cannot handle $reftype-ref arguments"; } else { $swash{$item} = $code; ++$assigned_code; } } carp "Malformed switch: action with no terms" if $code and ! $assigned_code; return sub { local($_) = @_; local $Case::action = sub { ($swash{$_[0]} || $default)->() }; &$Case::action; }; } 1;

Caution: Contents may have been coded under pressure.

In reply to Revision 2: Switch/case as a dispatch table with C-style fall-through by Roy Johnson
in thread Switch/case as a dispatch table with C-style fall-through by Roy Johnson

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!
  • 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, 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, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            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.
  • Log In?

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

    How do I use this? | Other CB clients
    Other Users?
    Others romping around the Monastery: (6)
    As of 2014-07-14 03:09 GMT
    Find Nodes?
      Voting Booth?

      When choosing user names for websites, I prefer to use:

      Results (254 votes), past polls