FAQ
~~ does not behave as documented. It claims that (Any, Object) will always
call the overloading on the rhs -- or die if none is present. Instead, it will
use the overloading on the lhs if the lhs is an object with overloading. This
indicates that we need *another dispatch line* in perlsyn, like this:

$a $b Type of Match Implied
=========== ======== ==============================
Overloaded Any invokes ~~ overloading on $a

It can't just be (Object, Any), because of the lhs is *not* overloaded, then
dispatch procedes as usual: it will require that the rhs be overloaded.

I have attached a heavily annotated test case to this email, which I hope will
make my point clear, or will help someone see how I have become mistaken.

There is a serious problem here: as Matt S. Trout pointed out on IRC, it means
that there are only two predictable cases:

1. (Any, undef)
2. (Overloaded, Any)

The first case is not more useful than existing mechanisms. The second case is
fine, except that "when" will always want to use the topic as the left hand
side, not the right, meaning that you can't properly use:

given ($x) {
when ($obj_test_1) { ... }
when ($obj_test_2) { ... }
when ($obj_test_3) { ... }
}

...because if $x is overloaded, it will be on the lhs of the implicit
$x~~$obj_test_1, and will change the sense of the test. Once again, given/when
can never behave predictably enough.

I will gladly write and apply a documentation bugfix for this, if we agree that
the docs are wrong -- but only if I can include some language declaring ~~ to
be a misfeature and best avoided. I promise not to include any profanity in
this patch.

--
rjbs

Search Discussions

  • Zefram at Jul 6, 2011 at 7:30 pm

    Ricardo Signes wrote:
    ~~ does not behave as documented. It claims that (Any, Object) will always
    call the overloading on the rhs -- or die if none is present. Instead, it will
    use the overloading on the lhs if the lhs is an object with overloading.
    Confirmed:

    $ perl -lwe '{ package A; use overload "~~" => sub { print "in overloaded match A"; }; } { package B; use overload "~~" => sub { print "in overloaded match B"; }; } my $a=bless({},"A"); my $b=bless({},"B"); print $a ~~ $b'
    in overloaded match A
    1
    indicates that we need *another dispatch line* in perlsyn, like this:
    It indicates that we need to change the behaviour. The changes in
    5.10.1 were meant to put the RHS in charge, and crucial to that is that
    the RHS's ~~ overloading takes precedence. It is not quite as crucial,
    but still advantageous, that the LHS's ~~ overloading is never used.
    Apparently we stuffed up the big fix.

    I haven't noticed, because I never use ~~, because it's so baroque. The
    only thing that's got me interested in it is the recent SmartMatch::Sugar.

    -zefram
  • Ricardo Signes at Jul 6, 2011 at 7:37 pm
    * Zefram [2011-07-06T15:29:59]
    Ricardo Signes wrote:
    indicates that we need *another dispatch line* in perlsyn, like this:
    It indicates that we need to change the behaviour.
    I'm fine with that, too. I wonder how much code it will break. I guess in the
    end, I don't care all that much. How could such code really expect to work
    reliably anyway?
    The changes in 5.10.1 were meant to put the RHS in charge, and crucial to
    that is that the RHS's ~~ overloading takes precedence. It is not quite as
    crucial, but still advantageous, that the LHS's ~~ overloading is never used.
    Apparently we stuffed up the big fix.
    I agree. In fact, I had a length digression about this in the test program
    before sending it, but removed it. I started to think that we'd decided that
    objects needed to "work" on the lhs without dying ($obj ~~ $refaddr) and so
    this crap slipped through.

    I think there was an actual thread about this, but didn't want to look for it.
    Maybe I'll try now.
    I haven't noticed, because I never use ~~, because it's so baroque. The
    only thing that's got me interested in it is the recent SmartMatch::Sugar.
    I agree, and never, ever use it. I found the above when explaining why not to
    use it -- someone said, "If your claim is correct, then perlsyn is wrong!"

    Ugh.

    --
    rjbs
  • Ricardo Signes at Jul 6, 2011 at 7:44 pm
    * Ricardo Signes [2011-07-06T15:36:49]
    I think there was an actual thread about this, but didn't want to look for it.
    Maybe I'll try now.
    It appears to be http://markmail.org/thread/4cieaoze5j3dmflh

    The summary of the desire to be strictly-RHS-based is here:

    http://markmail.org/message/yiv5eze7zru5b4qe

    The thread even includes: "So overloading applies only when the object is on
    the RHS. (to be clear)"

    --
    rjbs
  • Leon Timmermans at Jul 6, 2011 at 11:35 pm

    On Wed, Jul 6, 2011 at 9:36 PM, Ricardo Signes wrote:
    I'm fine with that, too.  I wonder how much code it will break.  I guess in the
    end, I don't care all that much.  How could such code really expect to work
    reliably anyway?
    If you mean changing it to what perlsyn claims it does, I suspect it's
    actually zero. Smartmatch overloading is a rarely used feature, but
    the odds of someone using it on both sides of a match is extremely
    small IMO. (fwiw, Smart::Match already deliberately fails when someone
    tries to use it on the left hand side and I might make it die in the
    future).

    Leon
  • Leon Timmermans at Jan 17, 2012 at 7:32 pm

    n Thu, Jul 7, 2011 at 1:35 AM, Leon Timmermans wrote:
    If you mean changing it to what perlsyn claims it does, I suspect it's
    actually zero. Smartmatch overloading is a rarely used feature, but
    the odds of someone using it on both sides of a match is extremely
    small IMO. (fwiw, Smart::Match already deliberately fails when someone
    tries to use it on the left hand side and I might make it die in the
    future).
    Thinking about it more, I'm think my patch is worth it. It may break
    an obscure corner case, but it brings some well needed sanity to
    smart-matching.

    Leon
  • Leon Timmermans at Jul 6, 2011 at 9:08 pm

    On Wed, Jul 6, 2011 at 9:29 PM, Zefram wrote:
    indicates that we need *another dispatch line* in perlsyn, like this:
    It indicates that we need to change the behaviour.  The changes in
    5.10.1 were meant to put the RHS in charge, and crucial to that is that
    the RHS's ~~ overloading takes precedence.  It is not quite as crucial,
    but still advantageous, that the LHS's ~~ overloading is never used.
    Apparently we stuffed up the big fix.
    I agree. This is a rather serous bug that goes completely against the
    spirit of smartmatching. I'd consider making it behave like perlsyn
    claims it does this a bugfix rather than a feature addition.

    Leon
  • Leon Timmermans at Jul 6, 2011 at 11:26 pm

    On Wed, Jul 6, 2011 at 11:08 PM, Leon Timmermans wrote:
    I agree. This is a rather serous bug that goes completely against the
    spirit of smartmatching. I'd consider making it behave like perlsyn
    claims it does this a bugfix rather than a feature addition.
    Oops, shouldn't have sent that patch just yet. It fixes the issue but
    makes two tests in t/op/smartmatch.t fail. It creates a failure if you
    match an object with smartmatch overloading with an object that has
    overloading but not for smartmatching (in case of the test,
    stringification overloading). I'm not sure that case is sane to begin
    with though.

    Leon
  • Leon Timmermans at Jul 6, 2011 at 11:25 pm

    On Wed, Jul 6, 2011 at 8:04 PM, Ricardo Signes wrote:

    ~~ does not behave as documented.  It claims that (Any, Object) will always
    call the overloading on the rhs -- or die if none is present.  Instead, it will
    use the overloading on the lhs if the lhs is an object with overloading.  This
    indicates that we need *another dispatch line* in perlsyn, like this:
    It turns out it's slightly more complicated. This bug only occurs if
    *both sides* are overloaded. As highest precedence match it does
    something like this:

    if (any overloading on righ hand side) {
    do smartmatch overloading on left or right, whichever is available
    }

    The most obvious fix would be to change that to

    if (smartmatch overloading on righ hand side) {
    do right hand smartmatch overloading
    }

    Ugh, this is a mess…

    Leon

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupperl5-porters @
categoriesperl
postedJul 6, '11 at 6:04p
activeJan 17, '12 at 7:32p
posts9
users3
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase