Skip Menu |

This queue is for tickets about the Match-Smart CPAN distribution.

Report information
The Basics
Id: 52635
Status: open
Priority: 0/
Queue: Match-Smart

People
Owner: Nobody in particular
Requestors: jpierce [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: 0.02



Subject: Update to true perl 6/5.10 smart matching
Hello, Is there any chance of seeing this updated to match the actual perl 6 spec, which has changed since Apocalypse 4? Some of the differences seem to be: module executes Code[+] Code[+] referential equality $a == $b modules is missing exists Hash Array hash slice existence grep {exists $a->{$_}} @$b module recurses Hash Any hash entry existence exists $a->{$b} module greps values?? Array Array arrays are identical[*] module recurses? Array Regex array grep grep /$b/, @$a Array Num array contains number grep $_ == $b, @$a Array Any array contains string grep $_ eq $b, @$a The current implementation yields the following results against a modified version of 5.10.0's smartmatch.t: 1..144 ok 1 - smart_match(\&foo, \&foo): 1 ok 2 - smart_match(\&foo, \&foo): 1 ok 3 - smart_match(\&foo, sub {}): ok 4 - smart_match(sub {}, \&foo): ok 5 - smart_match(\&foo, \&bar): not ok 6 - smart_match(\&bar, \&foo): 2 # Failed at smartmatch.t line 56 ok 7 - smart_match(1, sub{shift}): 1 ok 8 - smart_match(sub{shift}, 1): 1 ok 9 - smart_match(0, sub{shift}): ok 10 - smart_match(sub{shift}, 0): ok 11 - smart_match(1, sub{scalar @_}): 1 ok 12 - smart_match(sub{scalar @_}, 1): 1 ok 13 - smart_match([], \&bar): 2 ok 14 - smart_match(\&bar, []): 2 ok 15 - smart_match({}, \&bar): 2 ok 16 - smart_match(\&bar, {}): 2 ok 17 - smart_match(qr//, \&bar): 2 ok 18 - smart_match(\&bar, qr//): 2 ok 19 - smart_match(a_const, "a constant"): 1 ok 20 - smart_match("a constant", a_const): 1 ok 21 - smart_match(a_const, a_const): 1 ok 22 - smart_match(a_const, a_const): 1 ok 23 - smart_match(a_const, b_const): 1 ok 24 - smart_match(b_const, a_const): 1 not ok 25 - smart_match({}, {}): # Failed at smartmatch.t line 56 not ok 26 - smart_match({}, {}): # Failed at smartmatch.t line 56 ok 27 - smart_match({}, {1 => 2}): ok 28 - smart_match({1 => 2}, {}): ok 29 - smart_match({1 => 2}, {1 => 2}): 1 ok 30 - smart_match({1 => 2}, {1 => 2}): 1 ok 31 - smart_match({1 => 2}, {1 => 3}): 1 ok 32 - smart_match({1 => 3}, {1 => 2}): 1 ok 33 - smart_match({1 => 2}, {2 => 3}): ok 34 - smart_match({2 => 3}, {1 => 2}): ok 35 - smart_match(\%main::, {map {$_ => 'x'} keys %main::}): 1 ok 36 - smart_match({map {$_ => 'x'} keys %main::}, \%main::): 1 ok 37 - smart_match(\%hash, \%tied_hash): 1 ok 38 - smart_match(\%tied_hash, \%hash): 1 ok 39 - smart_match(\%tied_hash, \%tied_hash): 1 ok 40 - smart_match(\%tied_hash, \%tied_hash): 1 ok 41 - smart_match(\%::, [keys %main::]): 1 ok 42 - smart_match([keys %main::], \%::): 1 ok 43 - smart_match(\%::, []): ok 44 - smart_match([], \%::): Use of uninitialized value in hash element at /usr/lib/perl5/site_perl/5.8.8/Match/Smart.pm line 65, <DATA> line 113. ok 45 - smart_match({"" => 1}, [undef]): 1 Use of uninitialized value in hash element at /usr/lib/perl5/site_perl/5.8.8/Match/Smart.pm line 65, <DATA> line 113. ok 46 - smart_match([undef], {"" => 1}): 1 ok 47 - smart_match({ foo => 1 }, ["foo"]): 1 ok 48 - smart_match(["foo"], { foo => 1 }): 1 ok 49 - smart_match({ foo => 1 }, ["foo", "bar"]): 1 ok 50 - smart_match(["foo", "bar"], { foo => 1 }): 1 ok 51 - smart_match(\%hash, ["foo", "bar"]): 1 ok 52 - smart_match(["foo", "bar"], \%hash): 1 ok 53 - smart_match(\%hash, ["foo"]): 1 ok 54 - smart_match(["foo"], \%hash): 1 ok 55 - smart_match(\%hash, ["quux"]): ok 56 - smart_match(["quux"], \%hash): ok 57 - smart_match(\%hash, [qw(foo quux)]): 1 ok 58 - smart_match([qw(foo quux)], \%hash): 1 ok 59 - smart_match({foo => 1}, qr/^(fo[ox])$/): 1 ok 60 - smart_match(qr/^(fo[ox])$/, {foo => 1}): 1 ok 61 - smart_match(+{0..100}, qr/[13579]$/): ok 62 - smart_match(qr/[13579]$/, +{0..100}): ok 63 - smart_match(+{foo => 1, bar => 2}, "foo"): 1 ok 64 - smart_match("foo", +{foo => 1, bar => 2}): 1 ok 65 - smart_match(+{foo => 1, bar => 2}, "baz"): ok 66 - smart_match("baz", +{foo => 1, bar => 2}): not ok 67 - smart_match([], []): # Failed at smartmatch.t line 56 not ok 68 - smart_match([], []): # Failed at smartmatch.t line 56 ok 69 - smart_match([], [1]): ok 70 - smart_match([1], []): ok 71 - smart_match([["foo"], ["bar"]], [qr/o/, qr/a/]): 1 ok 72 - smart_match([qr/o/, qr/a/], [["foo"], ["bar"]]): 1 ok 73 - smart_match(["foo", "bar"], [qr/o/, qr/a/]): 1 ok 74 - smart_match([qr/o/, qr/a/], ["foo", "bar"]): 1 not ok 75 - smart_match(["foo", "bar"], [qr/o/, "foo"]): 1 # Failed at smartmatch.t line 56 not ok 76 - smart_match([qr/o/, "foo"], ["foo", "bar"]): 1 # Failed at smartmatch.t line 56 ok 77 - smart_match($deep1, $deep1): 1 ok 78 - smart_match($deep1, $deep1): 1 ok 79 - smart_match($deep1, $deep2): ok 80 - smart_match($deep2, $deep1): ok 81 - smart_match(\@nums, \@tied_nums): 1 ok 82 - smart_match(\@tied_nums, \@nums): 1 ok 83 - smart_match([qw(foo bar baz quux)], qr/x/): 1 ok 84 - smart_match(qr/x/, [qw(foo bar baz quux)]): 1 ok 85 - smart_match([qw(foo bar baz quux)], qr/y/): ok 86 - smart_match(qr/y/, [qw(foo bar baz quux)]): not ok 87 - smart_match([qw(1foo 2bar)], 2): # Failed at smartmatch.t line 56 not ok 88 - smart_match(2, [qw(1foo 2bar)]): # Failed at smartmatch.t line 56 ok 89 - smart_match([qw(1foo 2bar)], "2"): ok 90 - smart_match("2", [qw(1foo 2bar)]): ok 91 - smart_match(2, 2): 1 ok 92 - smart_match(2, 2): 1 ok 93 - smart_match(2, 3): ok 94 - smart_match(3, 2): ok 95 - smart_match(2, "2"): 1 ok 96 - smart_match("2", 2): 1 ok 97 - smart_match(2, "2.0"): 1 ok 98 - smart_match("2.0", 2): 1 not ok 99 - smart_match(2, "2bananas"): 1 # Failed at smartmatch.t line 56 not ok 100 - smart_match("2bananas", 2): 1 # Failed at smartmatch.t line 56 ok 101 - smart_match(2_3, "2_3"): ok 102 - smart_match("2_3", 2_3): ok 103 - smart_match(qr/x/, "x"): 1 ok 104 - smart_match("x", qr/x/): 1 ok 105 - smart_match(qr/y/, "x"): ok 106 - smart_match("x", qr/y/): ok 107 - smart_match(12345, qr/3/): 1 ok 108 - smart_match(qr/3/, 12345): 1 not ok 109 - smart_match(@nums, 7): # Failed at smartmatch.t line 56 not ok 110 - smart_match(7, @nums): # Failed at smartmatch.t line 56 not ok 111 - smart_match(@nums, \@nums): # Failed at smartmatch.t line 56 ok 112 - smart_match(\@nums, @nums): 2 ok 113 - smart_match(@nums, \\@nums): not ok 114 - smart_match(\\@nums, @nums): 2 # Failed at smartmatch.t line 56 not ok 115 - smart_match(@nums, [1..10]): # Failed at smartmatch.t line 56 ok 116 - smart_match([1..10], @nums): 2 ok 117 - smart_match(@nums, [0..9]): not ok 118 - smart_match([0..9], @nums): 1 # Failed at smartmatch.t line 56 not ok 119 - smart_match(%hash, "foo"): # Failed at smartmatch.t line 56 not ok 120 - smart_match("foo", %hash): # Failed at smartmatch.t line 56 not ok 121 - smart_match(%hash, /bar/): # Failed at smartmatch.t line 56 not ok 122 - smart_match(/bar/, %hash): # Failed at smartmatch.t line 56 not ok 123 - smart_match(%hash, [qw(bar)]): # Failed at smartmatch.t line 56 ok 124 - smart_match([qw(bar)], %hash): 1 ok 125 - smart_match(%hash, [qw(a b c)]): ok 126 - smart_match([qw(a b c)], %hash): not ok 127 - smart_match(%hash, %hash): # Failed at smartmatch.t line 56 not ok 128 - smart_match(%hash, %hash): # Failed at smartmatch.t line 56 not ok 129 - smart_match(%hash, {%hash}): # Failed at smartmatch.t line 56 ok 130 - smart_match({%hash}, %hash): 23 not ok 131 - smart_match(%hash, %tied_hash): # Failed at smartmatch.t line 56 not ok 132 - smart_match(%tied_hash, %hash): # Failed at smartmatch.t line 56 not ok 133 - smart_match(%tied_hash, %tied_hash): # Failed at smartmatch.t line 56 not ok 134 - smart_match(%tied_hash, %tied_hash): # Failed at smartmatch.t line 56 not ok 135 - smart_match(%hash, { foo => 5, bar => 10 }): # Failed at smartmatch.t line 56 ok 136 - smart_match({ foo => 5, bar => 10 }, %hash): 10 ok 137 - smart_match(%hash, { foo => 5, bar => 10, quux => 15 }): not ok 138 - smart_match({ foo => 5, bar => 10, quux => 15 }, %hash): 10 # Failed at smartmatch.t line 56 not ok 139 - smart_match(@nums, { 1, '', 2, '' }): # Failed at smartmatch.t line 56 not ok 140 - smart_match({ 1, '', 2, '' }, @nums): # Failed at smartmatch.t line 56 not ok 141 - smart_match(@nums, { 1, '', 12, '' }): # Failed at smartmatch.t line 56 not ok 142 - smart_match({ 1, '', 12, '' }, @nums): # Failed at smartmatch.t line 56 ok 143 - smart_match(@nums, { 11, '', 12, '' }): ok 144 - smart_match({ 11, '', 12, '' }, @nums):
Subject: smartmatch.patch
--- /opt/src/perl-5.10.0/t/op/smartmatch.t 2007-12-18 05:47:08.000000000 -0500 +++ smartmatch.t 2009-12-09 22:54:31.000000000 -0500 @@ -1,8 +1,8 @@ #!./perl BEGIN { - chdir 't'; - @INC = '../lib'; +# chdir 't'; +# @INC = '../lib'; require './test.pl'; } use strict; @@ -10,6 +10,8 @@ use Tie::Array; use Tie::Hash; +use Match::Smart 'smart_match'; + # The feature mechanism is tested in t/lib/feature/smartmatch: # This file tests the semantics of the operator, without worrying # about feature issues such as scoping etc. @@ -45,10 +47,10 @@ die "Bad test spec: ($yn, $left, $right)" unless $yn eq "" || $yn eq "!"; - my $tstr = "$left ~~ $right"; + my $tstr = $] >= 5.009 ? "$left ~~ $right" : "smart_match($left, $right)"; my $res; - $res = eval $tstr // ""; #/ <- fix syntax colouring + $res = eval $tstr || ""; #/ <- fix syntax colouring die $@ if $@ ne ""; ok( ($yn =~ /!/ xor $res), "$tstr: $res");
The attached patch makes the module behavior closer to perl 5.10's ~~ and also implements given/when a.k.a a switch statement. See also http://perladvent.org/2009/19/ However, the 5.10.1 smartmatch.t is more thorough, it would be worth adopting.
--- /usr/lib/perl5/site_perl/5.8.8/Match/Smart.pm 2004-02-03 22:26:34.000000000 -0500 +++ lib/Match/Smart.pm 2009-12-20 04:18:07.000000000 -0500 @@ -11,11 +11,11 @@ our @ISA = qw(Exporter); -our %EXPORT_TAGS = ( 'all' => [ qw( smart_match) ] ); +our %EXPORT_TAGS = ( 'all' => [ qw(smart_match given when default) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); -our $VERSION = '0.02'; +our $VERSION = '1.01'; ## initialize match look-up constants @@ -51,22 +51,29 @@ my @match_subs; -$match_subs[ARRAY ][ARRAY ] = sub { +$match_subs[ARRAY ][ARRAY ] = sub { + my $count = scalar @{$_[0]}; + return 0 unless $count == scalar @{$_[1]}; + + for(my $i=0; $i<$count; $i++){ + return 0 unless _smart_match($_[0][$i], $_[1][$i], $_[2]); + } + return 1; +}; +#Based on perlsyn it's unclear whether this should be grep or short-circuiting +$match_subs[ARRAY ][CODE ] = sub { !grep { !$_[1]->($_) } @$_[0] }; +$match_subs[ARRAY ][HASH ] = sub { for my $v (@{$_[0]}) { - for my $t (@{$_[1]}) { - return 1 if _smart_match($v, $t, $_[2]); - } + return 1 if exists $_[1]->{$v} } return; }; -$match_subs[ARRAY ][CODE ] = sub { $_[1]->(@{$_[0]}) }; -$match_subs[ARRAY ][HASH ] = sub { +$match_subs[ARRAY ][NUMBER] = sub { for my $v (@{$_[0]}) { - return 1 if $_[1]->{$v} + return 1 if _smart_match($v, $_[1], $_[2]); } return; }; -$match_subs[ARRAY ][NUMBER] = sub { $_[0]->[$_[1]] }; $match_subs[ARRAY ][OBJECT] = sub { for my $v (@{$_[0]}) { return 1 if _smart_match($v, $_[1], $_[2]); @@ -94,8 +101,10 @@ return; }; -$match_subs[CODE ][CODE ] = sub { $_[0]->(&{$_[1]}) }; -$match_subs[CODE ][HASH ] = sub { $_[0]->(%{$_[1]}) }; +#Swapped order of code-code to match 5.10 perlsyn && dox +$match_subs[CODE ][CODE ] = sub { $_[1]->(&{$_[0]}) }; +#Based on perlsyn it's unclear whether this should be grep or short-circuiting +$match_subs[CODE ][HASH ] = sub { !grep { !$_[0]->($_) } keys %{$_[1]} }; $match_subs[CODE ][NUMBER] = sub { $_[0]->($_[1]) }; $match_subs[CODE ][OBJECT] = sub { $_[0]->($_[1]) }; $match_subs[CODE ][REF ] = sub { _smart_match($_[0], ${$_[1]}, $_[2]) }; @@ -105,10 +114,7 @@ $match_subs[CODE ][UNDEF ] = sub { $_[0]->($_[1]) }; $match_subs[HASH ][HASH ] = sub { - for my $v (keys %{$_[1]}) { - return 1 if exists $_[0]->{$v}; - } - return; + "@{[sort keys %{$_[0]}]}" eq "@{[sort keys %{$_[1]}]}"; }; $match_subs[HASH ][NUMBER] = sub { $_[0]->{$_[1]} }; $match_subs[HASH ][OBJECT] = undef; @@ -244,6 +250,20 @@ } +sub given($&) { + local $_ = $_[0]; + eval{ $_[1]->() }; + return @{$@} +} + +sub when($&) { + die([$_[1]->()]) if smart_match($_, $_[0]); +} + +sub default(&) { + die([$_[0]->()]); +} + 1; __END__ =head1 NAME @@ -262,19 +282,29 @@ print "$amount is less than 10\n"; } + + use Match::Smart qw/ :all /; + + given $fruit => sub { + when [qw/Honeycrisp Jonagold Braeburn/] => sub{ print "apple\n" }; + when [qw/Concord Red_Flame/] => sub{ print "grape\n" }; + default { print "Unknown fruit: $_\n" }; + } + =head1 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. +C<Match::Smart> provides a easy means of testing whether two variables match +based upon a set of rules derived from the syntax of Perl 5.10 & Apocalypse 4. -The means of matching is based heavily on the Apocalypse 4, Perl 6 document by -Larry Wall. +It also provides an analog for Perl 5.10's version of a switch statement. =head1 EXPORT -Nothing is exported by default. The C<smart_match()> subroutine can be exported -if desired. +Nothing is exported by default. + +The C<smart_match()> subroutine can be exported if desired. + +The I<:all> tag will provide the necessary routines for switching. =head1 FUNCTIONS @@ -303,10 +333,11 @@ $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 ARRAY smart_match($val1->[$_], $val2->[$_]) for 0 .. $#$val1 + && $#$val1 == $#$val2 + ARRAY CODE !grep { !$val2->($_) } @{$val1} + ARRAY HASH grep { exists $val2->{$_} } @{$val1} + ARRAY NUMBER smart_match($_, $val2) for @$val1 ARRAY OBJECT grep { smart_match($_, $val2) } @{$val1} ARRAY REF grep { smart_match($_, ${$val2}) } @{$val1} ARRAY REGEXP grep { smart_match($_, $val2) } @{$val1} @@ -314,8 +345,8 @@ ARRAY STRING grep { smart_match($_, $val2) } @{$val1} ARRAY UNDEF grep { smart_match($_, $val2) } @{$val1} - CODE CODE $val1->(&{$val2}) - CODE HASH $val1->(%{$val2}) + CODE CODE $val2->(&{$val1}) + CODE HASH !grep { !$val1->($_) } keys %{$val2} CODE NUMBER $val1->($val2) CODE OBJECT $val1->($val2) CODE REF smart_match($val1, ${$val2}) @@ -324,7 +355,7 @@ CODE STRING $val1->($val2) CODE UNDEF $val1->($val2) - HASH HASH grep { exists $val1->{$_} } keys %{$val2} + HASH HASH smart_match(keys %{$val1}, keys %{$val2}) HASH NUMBER $val1->{$val2} HASH OBJECT - HASH REF smart_match($val1, ${$val2}) @@ -374,6 +405,8 @@ =over 4 +=item - test against perl 5.10.1 t/op/smartmatch.t + =item - handle GLOB and LVALUE ref types =item - provide a means of registering comparisons for specific Object types @@ -387,10 +420,14 @@ Apocalypse 4: http://www.perl.com/pub/a/2002/01/15/apo4.html?page=2 +Perl 5.10 syntax: http://perldoc.perl.org/perlsyn.html#Smart-matching-in-detail + =head1 AUTHOR Daniel B. Boorstein, E<lt>danboo@cpan.orgE<gt> +With contributions from Jerrad Pierce. + =head1 COPYRIGHT AND LICENSE Copyright 2004 by Daniel B. Boorstein
On Sun Dec 20 04:53:08 2009, JPIERCE wrote: Show quoted text
> The attached patch makes the module behavior closer to perl 5.10's ~~ > and also implements given/when a.k.a a switch statement. > > See also http://perladvent.org/2009/19/ > > However, the 5.10.1 smartmatch.t is more thorough, > it would be worth adopting.
I haven't touched this in years. I'll probably move the repo over to github, and look into adding this patch. If I'd known you were planning to use it in the Advent Calendar I'd have done it already. Though demonstrating the patching is probably quite instructive. Thanks Jerrad
Subject: Re: [rt.cpan.org #52635] Update to true perl 6/5.10 smart matching
Date: Sun, 20 Dec 2009 11:38:27 -0500
To: bug-Match-Smart [...] rt.cpan.org
From: Jerrad Pierce <belg4mit [...] pthbb.org>
Show quoted text
>If I'd known you were planning to use it in the Advent Calendar I'd have >done it already. Though demonstrating the patching is probably quite >instructive.
I know, sorry about that. But we're hurting for entries, so waiting to post, especially after a lack of repsonse to the initial ticket, wasn't a very appealing option. As soon as I got it to work, it went up... 10 hours in. It actually wasn't that hard, other than fighting with 5.10.x Re numish; and (lack of) prototypes for argument flattening and switch implementation. Cheers! -- Free map of local environmental resources: http://CambridgeMA.GreenMap.org -- MOTD on Prickle-Prickle, the 62nd of The Aftermath, in the YOLD 3175: Alternative smock. --JP
And finally, a head start on the 5.10.1 test, which highlights some particular object behaviors that might not be replicatable, at least not without something like: provide a means of registering comparisons for specific Object types (call Class->smart_match() method to get class to fill in require ments) by defining a UNIVERSAL method? I dunno, short on sleep. In any event, as fun as this is it's as far as I go for now, other duties are calling. perl -Mlib=lib smartmatch.t | & grep -E '^not' not ok 5 - smart_match(\%hash, undef) does not match not ok 6 - smart_match({}, undef) does not match not ok 23 - smart_match(\&fatal, $ov_obj) does not match not ok 24 - smart_match('cigam', $ov_obj) matches not ok 28 - smart_match({ cigam => 1 }, $ov_obj) does not match not ok 29 - smart_match({ stringified => 1 }, $ov_obj) does not match not ok 30 - smart_match($obj, $ov_obj) does not match not ok 32 - smart_match($obj, $obj) dies not ok 36 - smart_match(\&FALSE, $obj) dies not ok 37 - smart_match(\&foo, $obj) dies not ok 38 - smart_match(sub { 1 }, $obj) dies not ok 39 - smart_match(sub { 0 }, $obj) dies not ok 40 - smart_match(%keyandmore, $obj) dies not ok 42 - smart_match(@fooormore, $obj) dies not ok 46 - smart_match("key", $obj) dies not ok 48 - smart_match($obj, $str_obj) dies not ok 51 - smart_match(\&FALSE, $str_obj) dies not ok 52 - smart_match(\&foo, $str_obj) dies not ok 53 - smart_match(sub { 1 }, $str_obj) dies not ok 54 - smart_match(sub { 0 }, $str_obj) dies not ok 55 - smart_match(%keyandmore, $str_obj) dies not ok 57 - smart_match(@fooormore, $str_obj) dies not ok 61 - smart_match("object", $str_obj) dies not ok 63 - smart_match($ov_obj, $str_obj) does not match not ok 65 - smart_match($obj, qr/NoOverload/) matches not ok 66 - smart_match($ov_obj, qr/^stringified$/) matches not ok 73 - smart_match($str_obj, "object") matches not ok 74 - smart_match($ov_obj, 'magic') matches not ok 76 - smart_match(sub{0}, sub { ref $_[0] eq "CODE" }) matches not ok 78 - smart_match(%fooormore, sub { $_[0] =~ /^(foo|or|less)$/ }) does not match not ok 83 - smart_match(@fooormore, sub { $_[0] =~ /^(foo|or|more)$/ }) matches not ok 85 - smart_match(\@fooormore, sub { $_[0] =~ /^(foo|or|more)$/ }) matches not ok 86 - smart_match(\@fooormore, sub { $_[0] =~ /^(foo|or|less)$/ }) does not match not ok 87 - smart_match([@fooormore], sub { $_[0] =~ /^(foo|or|more)$/ }) matches not ok 88 - smart_match([@fooormore], sub { $_[0] =~ /^(foo|or|less)$/ }) does not match not ok 90 - smart_match(@fooormore, sub{@_==1}) matches not ok 93 - smart_match(/fooormore/, sub{ref $_[0] eq 'Regexp'}) matches not ok 102 - smart_match([1], \&bar) matches not ok 105 - smart_match([1], \&foo) does not match not ok 109 - smart_match([], \&foo) matches not ok 111 - smart_match(@empty, \&foo) matches not ok 112 - smart_match(%empty, \&foo) matches not ok 122 - smart_match([], \&fatal) matches not ok 124 - smart_match(@empty, \&fatal) matches not ok 125 - smart_match(%empty, \&fatal) matches not ok 126 - smart_match(sub {0}, qr/^CODE/) matches not ok 127 - smart_match(sub {0}, sub { ref shift eq "CODE" }) matches not ok 142 - smart_match(%hash, %tied_hash) matches not ok 143 - smart_match(%hash, %tied_hash) matches not ok 144 - smart_match(%tied_hash, %tied_hash) matches not ok 151 - smart_match(%refh, %refh) matches not ok 162 - smart_match(@empty, {}) does not match not ok 163 - smart_match(@empty, {}) does not match not ok 180 - smart_match(@fooormore, { foo => 1, or => 2, more => 3 }) matches not ok 181 - smart_match(@fooormore, { foo => 1, or => 2, more => 3 }) matches not ok 182 - smart_match(@fooormore, %fooormore) matches not ok 183 - smart_match(@fooormore, %fooormore) matches not ok 184 - smart_match(@fooormore, \%fooormore) matches not ok 185 - smart_match(@fooormore, \%fooormore) matches not ok 200 - smart_match(/B/i, {b=>2}) matches not ok 201 - smart_match(/B/i, {b=>2}) matches not ok 207 - smart_match("foo", %fooormore) matches not ok 218 - smart_match(undef, { hop => 'zouu' }) does not match not ok 220 - smart_match(undef, +{"" => "empty key"}) does not match not ok 221 - smart_match(undef, {}) does not match not ok 228 - smart_match([qr/o/, qr/a/], ["foo", "bar"]) does not match not ok 239 - smart_match(@nums, \@tied_nums) matches not ok 240 - smart_match(@nums, \@tied_nums) matches not ok 243 -# Failed at smartmatch.t line 108 not ok 244 - smart_match(@nums, @tied_nums) matches not ok 251 - smart_match(/x/, [qw(foo bar baz quux)]) matches not ok 252 - smart_match(/x/, [qw(foo bar baz quux)]) matches not ok 255 - smart_match(/FOO/i, @fooormore) matches not ok 256 - smart_match(/FOO/i, @fooormore) matches #not ok 263 - smart_match("2", [qw(1foo 2bar)]) does not match #numish not ok 266 - smart_match(undef, [1, 2, [undef], 4]) does not match #not ok 286 - "2" ~~ 2 matches #numish #not ok 288 - "2.0" ~~ 2 matches #numish #not ok 289 - smart_match(2, "2bananas") does not match #numish #not ok 291 - "2_3" ~~ 2_3 does not match #numish not ok 299 - smart_match(@fooormore, "".\@fooormore) matches not ok 302 - smart_match(%keyandmore, "".\%fooormore) does not match not ok 303 - smart_match(7, @nums) matches #?! not ok 304 - smart_match(@nums, \@nums) matches #?! not ok 306 - smart_match(@nums, [1..10]) matches #?! not ok 308 - smart_match("foo", %hash) matches #?! not ok 309 - smart_match(/bar/, %hash) matches #?! not ok 312 - smart_match(%hash, %hash) matches #?! not ok 313 - smart_match(%hash, +{%hash}) matches #op precedence, not fixable not ok 314 - smart_match(%hash, \%hash) matches #?! not ok 315 - smart_match(%hash, %tied_hash) matches #?! not ok 316 - smart_match(%tied_hash, %tied_hash) matches #?! not ok 317 - smart_match(%hash, { foo => 5, bar => 10 }) matches #?! not ok 319 - smart_match(@nums, { 1, '', 2, '' }) matches #?! not ok 320 - smart_match(@nums, { 1, '', 12, '' }) matches #?!
--- /opt/src/perl-5.10.1/t/op/smartmatch.t 2009-07-03 08:22:58.000000000 -0400 +++ smartmatch.t 2009-12-20 12:01:17.000000000 -0500 @@ -1,8 +1,8 @@ #!./perl BEGIN { - chdir 't'; - @INC = '../lib'; +# chdir 't'; +# @INC = '../lib'; require './test.pl'; } use strict; @@ -13,6 +13,8 @@ use Tie::Hash; use Tie::RefHash; +eval "use Match::Smart 'smart_match'" unless $] >= 5.009; + # Predeclare vars used in the tests: my @empty; my %empty; @@ -42,7 +44,7 @@ { package Test::Object::WithOverload; - sub new { bless { key => ($_[1] // 'magic') } } + sub new { bless { key => ($_[1] || 'magic') } } use overload '~~' => sub { my %hash = %{ $_[0] }; if ($_[2]) { # arguments reversed ? @@ -81,7 +83,7 @@ die "Bad test spec: ($yn, $left, $right)" if $yn =~ /[^!@=]/; - my $tstr = "$left ~~ $right"; + my $tstr = $] >= 5.009 ? "$left ~~ $right" : "smart_match($left, $right)"; test_again: my $res; @@ -108,8 +110,8 @@ } if ( $yn =~ s/=// ) { - $tstr = "$right ~~ $left"; - goto test_again; + my $tstr = $] >= 5.009 ? "$right ~~ $left" : "smart_match($right, $left)"; + goto test_again; } } @@ -159,7 +161,7 @@ ! [] undef ! %tied_hash undef ! @tied_nums undef -! $deep1 undef +#! $deep1 undef ! /foo/ undef ! qr/foo/ undef ! 21..30 undef
On Sun Dec 20 15:15:02 2009, JPIERCE wrote: Show quoted text
Mmm, apparently to match *current* 5.10 *behavior* (but not documentation) These warnings need to be "fatal" instead of ignored :-/ $match_subs[NUMBER][STRING] = sub { no warnings 'numeric'; $_[0] == $_[1] };
: : See also http://rt.perl.org/rt3/Public/Bug/Display.html?id=71452 : : Mmm, apparently to match *current* 5.10 *behavior* (but not documentation) : : These warnings need to be "fatal" instead of ignored :-/ : $match_subs[NUMBER][STRING] = sub { no warnings 'numeric'; $_[0] == $_[1] }; Actually, it just needs to be a simple return, as with undefs. this gets the 5.10.0 test suite failures down to just three: not ok 5 - smart_match(\&foo, \&bar): 2 not ok 87 - smart_match([qw(1foo 2bar)], 2): not ok 88 - smart_match(2, [qw(1foo 2bar)]): The code-code (which is correct), and 2 ~~ [qw/1foo 2bar/] which appears to be an incorrect test since 5.10.1 has different tests: ! "2" [qw(1foo 2bar)] "2bar" [qw(1foo 2bar)] And running 5.10.1 against the 5.10.0 test suite yields: not ok 87 - [qw(1foo 2bar)] ~~ 2: # Failed at op/smartmatch.t line 54 not ok 88 - 2 ~~ [qw(1foo 2bar)]: # Failed at op/smartmatch.t line 54