summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/smartmatch/engine/rjbs.pm45
1 files changed, 38 insertions, 7 deletions
diff --git a/lib/smartmatch/engine/rjbs.pm b/lib/smartmatch/engine/rjbs.pm
index 6f0d964..cf5aa91 100644
--- a/lib/smartmatch/engine/rjbs.pm
+++ b/lib/smartmatch/engine/rjbs.pm
@@ -5,25 +5,56 @@ use warnings;
use overload ();
use Scalar::Util qw(blessed reftype);
+sub type {
+ my ($thing) = @_;
+
+ if (!defined($thing)) {
+ return 'undef';
+ }
+ elsif (!ref($thing)) {
+ return 'unknown non-ref';
+ }
+ elsif (reftype($thing) eq 'REGEXP') {
+ return 'Regex';
+ }
+ elsif (blessed($thing)) {
+ if (overload::Method($thing, '~~')) {
+ return 'Overloaded';
+ }
+ elsif (overload::Method($thing, '=~')) {
+ return 'Regex';
+ }
+ else {
+ return 'unknown object';
+ }
+ }
+ elsif (reftype($thing) eq 'CODE') {
+ return 'Code';
+ }
+ else {
+ return 'unknown';
+ }
+}
+
sub match {
my ($a, $b) = @_;
- if (!defined($b)) {
+ if (type($b) eq 'undef') {
return !defined($a);
}
- elsif (blessed($b) && (my $overload = overload::Method($b, '~~'))) {
+ elsif (type($b) eq 'Overloaded') {
+ my $overload = overload::Method($b, '~~');
return $b->$overload($a, 1);
}
- elsif (reftype($b) eq 'REGEXP') {
- return $a =~ $b;
- }
- elsif (blessed($b) && overload::Method($b, '=~')) {
+ elsif (type($b) eq 'Regex') {
return $a =~ $b;
}
- elsif (!blessed($b) && reftype($b) eq 'CODE') {
+ elsif (type($b) eq 'Code') {
return $b->($a);
}
else {
+ $a //= 'undef';
+ $b //= 'undef';
die "invalid smart match: $a ~~ $b";
}
}