The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

   Match::Smart - best-guess matching of two scalars

SYNOPSIS

   use Match::Smart qw/ smart_match /;

   if (smart_match( $user, qr/^dan/ )) {
      print "You might be a dan\n";
   }

   if (smart_match( $amount, sub { $_[0] < 10} )) {
      print "$amount is less than 10\n";
   }

DESCRIPTION

   C<Match::Smart> provides a easy means of testing whether two scalars match.
   A best guess on how they should be compared is made, based on the types of
   the two scalars.

   The means of matching is based heavily on the Apocalypse 4, Perl 6 document
   by Larry Wall.

EXPORT

   Nothing is exported by default. The C<smart_match()> subroutine can be
   exported if desired.

FUNCTIONS

smart_match($val1, $val2)
   Attempts to do the right thing in I<matching> the two given values. Returns
   true if the two values I<match>, false otherwise.

   If both values are references, referring to the same thing, they are assumed
   to match.

   The table below describes how the comparisons are performed. Those described
   using C<grep> only do so for conciseness. The implementation uses C<for>
   loops to allow short-circuiting as soon as a match is determined.

   The order in which the values are passed to C<smart_match()> only affects
   the return value when comparing two CODE references. Therefore, the table
   below only shows half of the necessary comparisons (those missing can be
   inferred).

   Those noted as '-' are not currently defined and will result in fatal
   run-time exceptions.


      $val1    $val2    true if ...
      =====    =====    ===========

      ARRAY    ARRAY    any in @{$val1} smart_match any in @{$val2}
      ARRAY    CODE     $val2->(@{$val1})
      ARRAY    HASH     grep { $val2->{$_} } @{$val1}
      ARRAY    NUMBER   $val1->[$val2]
      ARRAY    OBJECT   grep { smart_match($_, $val2)    } @{$val1}
      ARRAY    REF      grep { smart_match($_, ${$val2}) } @{$val1}
      ARRAY    REGEXP   grep { smart_match($_, $val2)    } @{$val1}
      ARRAY    SCALAR   grep { smart_match($_, ${$val2}) } @{$val1}
      ARRAY    STRING   grep { smart_match($_, $val2)    } @{$val1}
      ARRAY    UNDEF    grep { smart_match($_, $val2)    } @{$val1}

      CODE     CODE     $val1->(&{$val2})
      CODE     HASH     $val1->(%{$val2})
      CODE     NUMBER   $val1->($val2)
      CODE     OBJECT   $val1->($val2)
      CODE     REF      smart_match($val1, ${$val2})
      CODE     REGEXP   $val1->($val2)
      CODE     SCALAR   smart_match($val1, ${$val2})
      CODE     STRING   $val1->($val2)
      CODE     UNDEF    $val1->($val2)

      HASH     HASH     grep { exists $val1->{$_} } keys %{$val2}
      HASH     NUMBER   $val1->{$val2}
      HASH     OBJECT   -
      HASH     REF      smart_match($val1, ${$val2})
      HASH     REGEXP   grep { $_ =~ $val2 } keys %{$val1}
      HASH     SCALAR   smart_match($val1, ${$val2})
      HASH     STRING   $val1->{$val2}
      HASH     UNDEF    -

      NUMBER   NUMBER   $val1 == $val2
      NUMBER   OBJECT   -
      NUMBER   REF      smart_match($val1, ${$val2})
      NUMBER   REGEXP   $val1 =~ $val2
      NUMBER   SCALAR   smart_match($val1, ${$val2})
      NUMBER   STRING   $val1 == $val2
      NUMBER   UNDEF    ** ALWAYS FALSE **

      OBJECT   OBJECT   $val1 == $val2
      OBJECT   REF      smart_match($val1, ${$val2})
      OBJECT   REGEXP   -
      OBJECT   SCALAR   smart_match($val1, ${$val2})
      OBJECT   STRING   $val1->can($val2) && $val1->$val2
      OBJECT   UNDEF    ** ALWAYS FALSE **

      REF      REF      smart_match(${$val1}, ${$val2})
      REF      REGEXP   smart_match(${$val1}, $val2)
      REF      SCALAR   smart_match(${$val1}, ${$val2})
      REF      STRING   smart_match(${$val1}, $val2)
      REF      UNDEF    smart_match(${$val1}, $val2)

      REGEXP   REGEXP   $val1 eq $val2
      REGEXP   SCALAR   smart_match($val1, ${$val2})
      REGEXP   STRING   $val2 =~ $val1
      REGEXP   UNDEF    ** ALWAYS FALSE **

      SCALAR   SCALAR   smart_match(${$val1}, ${$val2})
      SCALAR   STRING   smart_match(${$val1}, $val2)
      SCALAR   UNDEF    smart_match(${$val1}, $val2)

      STRING   STRING   $val1 eq $val2
      STRING   UNDEF    ** ALWAYS FALSE **

      UNDEF    UNDEF    ** ALWAYS TRUE **

TO DO

- handle GLOB and LVALUE ref types
- provide a means of registering comparisons for specific Object types (call Class->smart_match() method to get class to fill in requirements)
- allow the comparison methods to be overridden

SEE ALSO

Apocalypse 4: http://www.perl.com/pub/a/2002/01/15/apo4.html?page=2

AUTHOR

Daniel B. Boorstein, <danboo@cpan.org>

COPYRIGHT AND LICENSE

Copyright 2004 by Daniel B. Boorstein

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.