FAQ
I was going over smart matches earlier this week and ran into an
inconsistancy that is confusing me. Let me show you a test case.

#!perl -w

use strict;
use feature qw(~~);

use Devel::Peek;
use Test::More qw(no_plan);

my $string = "5 hundred";

ok(5 ~~ "5", "The number 5 matches the string 5");
ok(5 ~~ $string, "Fails. RHS not brought into numeric context");
ok("5 hundred" ~~ 5, "Fails. It is commutative");

diag Dump $string;

{
no warnings "numeric";
ok(5 == $string, "Passes. RHS is brought into numeric context");
}

diag Dump $string;

ok(5 ~~ $string, "Fails. RHS is numeric, but ~~ doesn't care");
__END__

I'm having difficulty understanding why all the smart matches but the
first do not pass. Just to check, I tried all the above in a pugs from
June 20th, and the results are the same.

So, let me talk through the results and our current documentation, and
maybe someone can help. From the Perl 5 docs, a string on one side
and a number on the other should force numeric or string equality, but
doesn't exactly say which. For me, if it DWIM, it would return true
if either would return true.

Anyways, the first test works as expected. 5 ~~ "5" is OK.

The fourth test does a numeric equals between the number 5 and the
string "5 days". The string is forced into numeric context and
compares 5 to 5, returning true, as expected.

The second test is confusing. It would appear that it only does the
string comparison, gets false, and quits there. That seems to go
against the documentation saying that a number compared to something
like a number does a numeric comparison. Commutitivity is working as
the third test shows. Finally, in the fifth test, even with the
string upgraded to a PVNV, the smart match appears to continue
with a string comparison.

It seems to me that smart matching between scalars just isn't very smart.
Possibly, the docs need to be cleaned up to indicate the full and
correct hierarchy for matching with smart match. The other possibility
is that the smart match needs to be smarter, attempting numeric
comparisons if one side looks numeric, as the documentation currently
specifies. This would make the code do more of what I mean, so it
feels more natural. Does anyone else agree or am I missing a piece
of the puzzle with regards to Perl 6?

Steve Peters
steve@fisharerojo.org

Search Discussions

  • Yitzchak Scott-Thoennes at Jun 29, 2006 at 10:01 pm

    Steve Peters wrote:
    I was going over smart matches earlier this week and ran into an
    inconsistancy that is confusing me. Let me show you a test case.

    #!perl -w

    use strict;
    use feature qw(~~);

    use Devel::Peek;
    use Test::More qw(no_plan);

    my $string = "5 hundred";

    ok(5 ~~ "5", "The number 5 matches the string 5");
    ok(5 ~~ $string, "Fails. RHS not brought into numeric context");
    ok("5 hundred" ~~ 5, "Fails. It is commutative");

    diag Dump $string;

    {
    no warnings "numeric";
    ok(5 == $string, "Passes. RHS is brought into numeric context");
    }

    diag Dump $string;

    ok(5 ~~ $string, "Fails. RHS is numeric, but ~~ doesn't care");
    __END__

    I'm having difficulty understanding why all the smart matches but the
    first do not pass. Just to check, I tried all the above in a pugs from
    June 20th, and the results are the same.

    So, let me talk through the results and our current documentation, and
    maybe someone can help. From the Perl 5 docs, a string on one side
    and a number on the other should force numeric or string equality, but
    doesn't exactly say which. For me, if it DWIM, it would return true
    if either would return true.
    So
    "0" ~~ !1
    "" ~~ !1
    0 ~~ !1
    would all be true? I don't like that; I'd expect "0" ~~ !1 to be false.
    Anyways, the first test works as expected. 5 ~~ "5" is OK.

    The fourth test does a numeric equals between the number 5 and the
    string "5 days". The string is forced into numeric context and
    compares 5 to 5, returning true, as expected.

    The second test is confusing. It would appear that it only does the
    string comparison, gets false, and quits there. That seems to go
    against the documentation saying that a number compared to something
    like a number does a numeric comparison. Commutitivity is working as
    the third test shows. Finally, in the fifth test, even with the
    string upgraded to a PVNV, the smart match appears to continue
    with a string comparison.
    It shouldn't depend on the PVNV, but on SvNIOKp.
    It seems to me that smart matching between scalars just isn't very smart.
    Possibly, the docs need to be cleaned up to indicate the full and
    correct hierarchy for matching with smart match. The other possibility
    is that the smart match needs to be smarter, attempting numeric
    comparisons if one side looks numeric, as the documentation currently
    specifies. This would make the code do more of what I mean, so it
    feels more natural. Does anyone else agree or am I missing a piece
    of the puzzle with regards to Perl 6?
    I really don't like the idea of ~~ doing more than one kind of match,
    and I'd think it should follow the lead of the bitops by doing a numeric
    compare if either operand was ever in a numeric context. But see thread
    at
    http://groups.google.com/groups?threadm=20050928200951.GA5652@efn.org
    for suggestions for changing that.

    But having it match what perl6 will do is even more important than having
    it make perfect sense, IMO.
  • Yitzchak Scott-Thoennes at Jun 30, 2006 at 6:35 am

    On Thu, Jun 29, 2006 at 03:00:59PM -0700, Yitzchak Scott-Thoennes wrote:
    So
    "0" ~~ !1
    "" ~~ !1
    0 ~~ !1
    would all be true? I don't like that; I'd expect "0" ~~ !1 to be false.
    That made sense when I wrote it, but contradicts what I say later:
    I really don't like the idea of ~~ doing more than one kind of match,
    and I'd think it should follow the lead of the bitops by doing a numeric
    compare if either operand was ever in a numeric context.
    (that is, has a numeric value, which sv_no does) which would indicate
    that "0" ~~ !1 would be true, while "" ~~ !1 would give a warning (ala
    "" == !1) and be true.
  • Rafael Garcia-Suarez at Jul 6, 2006 at 9:53 am

    Steve Peters wrote:

    So, let me talk through the results and our current documentation, and
    maybe someone can help. From the Perl 5 docs, a string on one side
    and a number on the other should force numeric or string equality, but
    doesn't exactly say which. For me, if it DWIM, it would return true
    if either would return true.
    To me that behaves as the docs say, notably the table in perlsyn :

    Any Str string equality $a eq $b
    Any Num numeric equality $a == $b

    You see that it's not symmetrical.
    I shall post a follow-up on the behaviour of smart match in P6.
  • Yitzchak Scott-Thoennes at Jul 6, 2006 at 4:53 pm

    Steve Peters wrote:
    So, let me talk through the results and our current documentation, and
    maybe someone can help. From the Perl 5 docs, a string on one side
    and a number on the other should force numeric or string equality, but
    doesn't exactly say which. For me, if it DWIM, it would return true
    if either would return true.
    To me that behaves as the docs say, notably the table in perlsyn :

    Any Str string equality $a eq $b
    Any Num numeric equality $a == $b

    You see that it's not symmetrical.
    I shall post a follow-up on the behaviour of smart match in P6.
    Bleah. The sequence (Any~~Str checks string equality, otherwise Any~~Num
    checks numeric equality, otherwise Any~~Any checks string equality) seems
    to imply string compare if SvPOKp($b) || ! SvNIOKp($b), otherwise numeric.
    Which kind of sucks, since, to me, using a number in a string context
    having an effect is more surprising than using a string in a numeric
    context having an effect.

    But it'd still be better to do it like perl6 will than to do it "right".

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupperl5-porters @
categoriesperl
postedJun 29, '06 at 7:55p
activeJul 6, '06 at 4:53p
posts5
users3
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase