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

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";
}

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.

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

Attempts to do the right thing in matching the two given values. Returns true if the two values 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 grep only do so for conciseness. The implementation uses for loops to allow short-circuiting as soon as a match is determined.
The order in which the values are passed to 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 **

Class->smart_match() method to get class to fill in requirements)
Apocalypse 4: http://www.perl.com/pub/a/2002/01/15/apo4.html?page=2

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

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.