Switch
view release on metacpan or search on metacpan
package Switch;
use 5.005;
use strict;
use vars qw($VERSION);
use Carp;
use if $] >= 5.011, 'deprecate';
$VERSION = '2.17';
# LOAD FILTERING MODULE...
use Filter::Util::Call;
sub __();
# CATCH ATTEMPTS TO CALL case OUTSIDE THE SCOPE OF ANY switch
$::_S_W_I_T_C_H = sub { croak "case/when statement not in switch/given block" };
my $offset;
my $fallthrough;
my ($Perl5, $Perl6) = (0,0);
sub import
{
$fallthrough = grep /\bfallthrough\b/, @_;
$offset = (caller)[2]+1;
filter_add({}) unless @_>1 && $_[1] eq 'noimport';
my $pkg = caller;
no strict 'refs';
for ( qw( on_defined on_exists ) )
{
*{"${pkg}::$_"} = \&$_;
}
*{"${pkg}::__"} = \&__ if grep /__/, @_;
$Perl6 = 1 if grep(/Perl\s*6/i, @_);
$Perl5 = 1 if grep(/Perl\s*5/i, @_) || !grep(/Perl\s*6/i, @_);
1;
}
sub unimport
{
filter_del()
}
sub filter
{
my($self) = @_ ;
local $Switch::file = (caller)[1];
my $status = 1;
$status = filter_read(1_000_000);
return $status if $status<0;
$_ = filter_blocks($_,$offset);
$_ = "# line $offset\n" . $_ if $offset; undef $offset;
return $status;
}
use Text::Balanced ':ALL';
sub line
{
my ($pretext,$offset) = @_;
($pretext=~tr/\n/\n/)+($offset||0);
}
sub is_block
{
local $SIG{__WARN__}=sub{die$@};
local $^W=1;
my $ishash = defined eval 'my $hr='.$_[0];
undef $@;
return !$ishash;
}
if $c_ref eq 'HASH';
return;
};
}
elsif ($s_ref eq 'Regexp')
{
$::_S_W_I_T_C_H =
sub { my $c_val = $_[0];
my $c_ref = ref $c_val;
return $c_val=~/s_val/ if $c_ref eq "";
return scalar grep {$_=~/s_val/} @$c_val
if $c_ref eq 'ARRAY';
return $c_val->($s_val) if $c_ref eq 'CODE';
return $c_val->call($s_val) if $c_ref eq 'Switch';
return $s_val eq $c_val if $c_ref eq 'Regexp';
return grep {$_=~/$s_val/ && $c_val->{$_}} keys %$c_val
if $c_ref eq 'HASH';
return;
};
}
elsif ($s_ref eq 'HASH')
{
$::_S_W_I_T_C_H =
sub { my $c_val = $_[0];
my $c_ref = ref $c_val;
return $s_val->{$c_val} if $c_ref eq "";
return scalar grep {$s_val->{$_}} @$c_val
if $c_ref eq 'ARRAY';
return $c_val->($s_val) if $c_ref eq 'CODE';
return $c_val->call($s_val) if $c_ref eq 'Switch';
return grep {$_=~/$c_val/ && $s_val->{"$_"}} keys %$s_val
if $c_ref eq 'Regexp';
return $s_val==$c_val if $c_ref eq 'HASH';
return;
};
}
elsif ($s_ref eq 'Switch')
{
$::_S_W_I_T_C_H =
sub { my $c_val = $_[0];
return $s_val == $c_val if ref $c_val eq 'Switch';
return $s_val->call(@$c_val)
if ref $c_val eq 'ARRAY';
return $s_val->call($c_val);
};
}
else
{
croak "Cannot switch on $s_ref";
}
return 1;
}
sub case($) { local $SIG{__WARN__} = \&carp;
$::_S_W_I_T_C_H->(@_); }
# IMPLEMENT __
my $placeholder = bless { arity=>1, impl=>sub{$_[1+$_[0]]} };
sub __() { $placeholder }
sub __arg($)
{
my $index = $_[0]+1;
bless { arity=>0, impl=>sub{$_[$index]} };
}
sub hosub(&@)
{
# WRITE THIS
}
sub call
{
my ($self,@args) = @_;
return $self->{impl}->(0,@args);
}
sub meta_bop(&)
{
my ($op) = @_;
sub
{
my ($left, $right, $reversed) = @_;
($right,$left) = @_ if $reversed;
my $rop = ref $right eq 'Switch'
? $right
: bless { arity=>0, impl=>sub{$right} };
my $lop = ref $left eq 'Switch'
? $left
: bless { arity=>0, impl=>sub{$left} };
my $arity = $lop->{arity} + $rop->{arity};
return bless {
arity => $arity,
impl => sub { my $start = shift;
return $op->($lop->{impl}->($start,@_),
$rop->{impl}->($start+$lop->{arity},@_));
}
};
};
}
sub meta_uop(&)
{
my ($op) = @_;
sub
{
my ($left) = @_;
my $lop = ref $left eq 'Switch'
? $left
: bless { arity=>0, impl=>sub{$left} };
my $arity = $lop->{arity};
return bless {
( run in 0.618 second using v1.01-cache-2.11-cpan-524268b4103 )