Skip Menu |
Report information
Id: 128931
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: zefram [at] fysh.org
Cc:
AdminCc:

Severity: (no value)
Tag: Bug
Platform: (no value)
Patch Status: (no value)
VM: (no value)



From: Zefram <zefram [...] fysh.org>
Date: Sun, 14 Aug 2016 20:46:10 +0100
Subject: [BUG] .WHICH doesn't distinguish identically-named classes
To: rakudobug [...] perl.org
Download (untitled) / with headers
text/plain 407b
Show quoted text
> ({ my class Aa {} }(), { my class Aa {} }()).map({ ($_.WHICH, $_.WHERE) })
((Aa 47040393861144) (Aa 47040393995944)) I've constructed two different classes here, each locally named "Aa". The .WHERE values confirm that they're physically distinct objects, and they're also shown to be distinct by ===. But .WHICH yields identical strings for them, erroneously indicating that they're identical. -zefram
There's a bit of confusion here in that (I'm assuming) REPL uses a .say or something similar to output the values. So when it output your list, it looked the same, but .WHICH doesn't return strings, but rather ObjAt objects. Even thought they get stringified to the same value via .gist, they are distinct objects and .WHICHes of different-yet-same-named objects are different and do not produce any conflicts, such as in === comparisons: <Zoffix> m: my $x = { my class Aa { has $!foo; }.new }(); my $y = { my class Aa { has $!bar }.new }(); say $x === $y; <camelia> rakudo-moar ee8a25: OUTPUT«False␤» You can see the returned ObjAt objects are different if you output their .WHERE addresses: <Zoffix> m: say ({ my class Aa { has $!foo; } }(), { my class Aa { has $!bar } }()).map({ $_.WHICH.WHERE }) <camelia> rakudo-moar ee8a25: OUTPUT«(140257421217584 140257421236784)␤» With that said, I'm rejecting this ticket. One can argue such ObjAt have to stringify to different values, but I'm failing to see the need to do so. If I'm wrong, please let me know and I'll reopen.
From: Zefram <zefram [...] fysh.org>
Date: Mon, 15 Aug 2016 11:33:04 +0100
Subject: Re: [perl #128931] [BUG] .WHICH doesn't distinguish identically-named classes
To: Zoffix Znet via RT <perl6-bugs-followup [...] perl.org>
Download (untitled) / with headers
text/plain 1.5k
Zoffix Znet via RT wrote: Show quoted text
>You can see the returned ObjAt objects are different if you output >their .WHERE addresses:
That kind of comparison distinguishes ObjAt values that *are* meant to be identical: Show quoted text
> 3 === 3
True Show quoted text
> 3.WHICH.WHERE == 3.WHICH.WHERE
False So in both these cases, the 3s and the classes, the ObjAt values are physically distinct but contain the same string. Is there some other way to compare ObjAt values, that shows 3s to be the same but my classes to be distinct? doc/Type/ObjAt.pod says # If two objects compare equally via C<===>, their C<.WHICH> methods return # the same ObjAt object. So in the above case with 3s it implies that these ObjAt objects are considered "the same" even though they're physically distinct. That is, ObjAt identity is functional. Show quoted text
>One can argue such ObjAt have to stringify to different values, but >I'm failing to see the need to do so. If I'm wrong, please let me know >and I'll reopen.
I believe you're wrong and this needs to be reopened. It appears that the intent of ObjAt is that its physical location is insignificant and that only the value it contains is significant. In that respect it's a functional data structure, like a large Int value. This approach obviously makes sense in order to permit separately-constructed functional objects (such as large Int values) to appear to have the same identity via .WHICH. Furthermore, as far as I can see the string is the entire content of an ObjAt. All the construction expressions are just wrapping up a string. So eq does seem to be the appropriate way to compare ObjAt values. -zefram
Subject: Re: [perl #128931] [BUG] .WHICH doesn't distinguish identically-named classes
To: Zoffix Znet via RT <perl6-bugs-followup [...] perl.org>
From: Zefram <zefram [...] fysh.org>
Date: Mon, 15 Aug 2016 12:02:07 +0100
Download (untitled) / with headers
text/plain 249b
I wrote: Show quoted text
>> 3 === 3
>True
>> 3.WHICH.WHERE == 3.WHICH.WHERE
>False
Additional: Show quoted text
> 3.WHICH === 3.WHICH
True Show quoted text
> { my class Aa {} }().WHICH === { my class Aa {} }().WHICH
True This seems to confirm that the string is the thing that matters. -zefram
Reopened.
Date: Mon, 15 Aug 2016 15:05:33 +0100
From: Zefram <zefram [...] fysh.org>
Subject: Re: [perl #128931] [BUG] .WHICH doesn't distinguish identically-named classes
To: Zoffix Znet via RT <perl6-bugs-followup [...] perl.org>
Download (untitled) / with headers
text/plain 384b
Additional additional phenomena: Show quoted text
> set({ my class Aa {} }(), { my class Aa {} }()).elems
1 Show quoted text
> set({ my class Aa {} }()).EXISTS-KEY({ my class Aa {} }())
True Looks like the Set class is using .WHICH strings, not === or anything else more effective, to decide distinctness for set membership purposes. That would be perfectly sensible if .WHICH reliably indicated identity. -zefram
From: Zefram <zefram [...] fysh.org>
Date: Wed, 17 Aug 2016 14:21:56 +0100
To: Zoffix Znet via RT <perl6-bugs-followup [...] perl.org>
Subject: Re: [perl #128931] [BUG] .WHICH doesn't distinguish identically-named classes
Download (untitled) / with headers
text/plain 292b
There was an attempt to fix this in 4d85cde9, and it does avoid clashes between class objects, but it's introduced a new kind of .WHICH clash: Show quoted text
> Int.WHICH
Int|29060856 Show quoted text
> for Int, 29060856 { say (.WHICH, .DEFINITE) }
(Int|29060856 False) (Int|29060856 True) Show quoted text
> Int === 29060856
True -zefram
From: Zefram <zefram [...] fysh.org>
Date: Wed, 23 Nov 2016 08:21:03 +0000
To: Zoffix Znet via RT <perl6-bugs-followup [...] perl.org>
Subject: Re: [perl #128931] [BUG] .WHICH doesn't distinguish identically-named classes
Download (untitled) / with headers
text/plain 573b
There was another attempt to fix this in 1b898c81, which does prevent clashes between the Int class object and defined Int values, and similar clashes for some other classes, but there remain other cases of this kind of .WHICH clash: Show quoted text
> Str.WHICH
Str|U43431280 Show quoted text
> for Str, "U43431280" { say (.WHICH, .DEFINITE) }
(Str|U43431280 False) (Str|U43431280 True) Show quoted text
> Str === "U43431280"
True Show quoted text
> ObjAt.WHICH
ObjAt|U43431256 Show quoted text
> for ObjAt, ObjAt.new("U43431256") { say (.WHICH, .DEFINITE) }
(ObjAt|U43431256 False) (ObjAt|U43431256 True) Show quoted text
> ObjAt === ObjAt.new("U43431256")
True -zefram


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org