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;