Switch-Right

 view release on metacpan or  search on metacpan

lib/Switch/Right.pm  view on Meta::CPAN

             }}
             return true;  # ...because every LHS/RHS combination has now failed to match
}

1; # Magic true value required at end of module
__END__

=head1 NAME

Switch::Right -  Switch and smartmatch done right this time


=head1 VERSION

This document describes Switch::Right version 0.000006


=head1 SYNOPSIS

    use Switch::Right;

    given ($value) {
        when (undef)    { say 'an undefined value'                         }
        when (1)        { say 'the number 1'                               }
        when ('two')    { say 'the string "two"'                           }
        when (\@array)  { say 'an identical arrayref'                      }
        when (\%hash)   { say 'an identical hashref (keys AND values)'     }
        when (qr/pat/)  { say 'a non-reference that matched the pattern'   }
        when (\&foo)    { say 'foo($value) returned true'                  }

        when ( /pat/)   { say 'a non-ref that matched the pattern'         }
        when (!/pat/)   { say 'a non-ref that didn't match the pattern'    }

        when (0 <= $_ <= 9)                { say 'a singe digit'           }
        when (defined && length > 0)       { say 'a non-empty string'      }
        when (-r || -w)                    { say 'an accessible file'      }
        when (exists $hash{$_})            { say 'a key of the hash'       }

        when ( any => [keys %hash])        { say 'a key of the hash'       }
        when ( any => [0..9])              { say 'a single-digit number'   }
        when ( all => [qr/foo/, qr/bar/])  { say 'matched /foo/ and /bar/' }
        when (none => \@prohibited)        { say 'not a prohibited value'  }

        default  { say 'none of the above'; }
    }


=head1 DESCRIPTION

After 17 years as a core feature of Perl,
C<'given'>/C<'when'> and smartmatching are going away.

And for some very good reasons! Smartmatching is just too damn clever
for most people (including its inventor!) to be able to easily remember
L<all the rules|https://perldoc.perl.org/5.40.0/perlop#Smartmatch-Operator>
about what matched what.

And the weird extra-special special-case behaviour of some (but not all) boolean expressions
in a C<when> only makes things even worse.

Hindsight is supposedly 20/20 and E<mdash> in hindsight E<mdash> smartmatching
should have been a lot simpler, a lot more explicit, and a lot easier to remember/predict.

That's what this module attempts to accomplish: to redesign the smartmatching
and the C<given>/C<when> mechanisms so that they're easier to use and easier
to understand.

It implements a version of smartmatching with only six rules to remember,
eliminates all of that magical auto-distributivity of C<when> expressions,
and provides clearer and more explicit ways to specify all those complicated
and hard-to-remember special-case I<"match any of..."> and I<"match all of...">
behaviours.

You could think of it as the C<'switch'> feature from an alternate timeline,
Or you can think of it as a second chance: switch re-imagined...and done right this time.

Above all, this module is supposed to be I<useful>. Once you're using Perl v5.42
you won't be able to write the old standard C<given>/C<when> blocks any more,
but you'll still be able to write these new C<given>/C<when> blocks,
with simpler semantics and clearer syntax.


=head1 INTERFACE

=head2 C<given>/C<when> redesigned

This module aims to greatly simplify the way that C<given>/C<when> switches operate.
Mostly by L<greatly simplifying the smartmatching behaviours|"Smartmatching re-imagined">
that a switch employs to select which C<when> to execute within its C<given>.

The C<given>/C<when>/C<default> syntax itself has not been significantly changed,
with only one major addition: L<explicit junctives|"Junctive smartmatching">,
which replace most of the previous complex magic of smartmatching.

The C<given> block still takes a single argument, which is evaluated in scalar context,
and then aliased to a localized C<$_> in the scope of the C<given>'s block.
The argument to the C<given> is still simplified at compile-time. If the argument
is an array, an array slice, a hash, or a kv-slice, it is still automatically
converted to a reference (i.e. rather than to a count).

A C<when> block still takes a single argument, which is still compile-time
folded and auto-enreferenced. The argument is still evaluated in scalar context,
and then smartmatched against C<$_> (but now using the L<new simplified
smartmatch semantics|"Smartmatching re-imagined">). If the C<when>'s argument
successfully smartmatches then its block is executed. At the end of that block,
control then immediately jumps out of the surrounding C<given> or C<for>.

A C<default> block still takes a no argument and unconditionally executes its block,
after which control then immediately jumps out of the surrounding C<given> or C<for>.

A call to the C<break> function immediately jumps out of the surrounding C<given> block.

A call to the C<continue> function immediately jumps out of the surrounding C<when> block
and moves on to the following statement within the current C<given> or C<for>.

=head3 Differences from the old built-in C<given>/C<when>

=head4 Junctive C<given>/C<when> arguments

Apart from the major changes in L<how C<given>/C<when> smartmatches|"Smartmatching re-imagined">,
the most significant difference in this new approach is that some arguments



( run in 0.410 second using v1.01-cache-2.11-cpan-71847e10f99 )