Uh, nice brain twister.
It sounds obvious at first that if an object had a reference to itself, this invariant would stay even when exchanging its identity.
But actually “become” means that every slot that was pointing to the one object is now pointing to the other. So yes, that array now must point to the new object if it formerly pointed to the array.
With a one-way “b becomeForward: a” of course it’s different, because only references to ‘b’ are replaced with references to ‘a’, references to ‘a’ are not touched at all.
So David’s right, there is no bug.
- Bert -
On 31.01.2016, at 00:24, David T. Lewis lewis@mail.msen.com wrote:
I don't think this is a bug.
If I do this: b := 'This is a string'.
instead of this: b := Object new.
then your example seems seems to behave exactly as I would expect. The thing that 'b' points to is an array with an array containing the string. The thing that 'a' now points to is the same string because of the two way become.
Dave
On Sat, Jan 30, 2016 at 04:58:28PM -0500, Florin Mateoc wrote:
Hi all,
Perhaps this is a known bug, since apparently it's been there forever, but now that we have a shiny new vm, it might be the right time to fix it. If we do:
| a b |
a := Array new: 1. a at: 1 put: (Array with: a).
At this point, as expected, evaluating
a first first == a
returns true. But if we then do:
b := Object new. a become: b.
then
((b at: 1) at: 1) == b
returns false. Instead
((b at: 1) at: 1) == a
returns true.
This obvious bug happens in all the VMs (I tried with Squeak 2.8 and 5)
Florin
P.S. Wow, I just tried this in VA and in VW. In VA it works correctly (except it has to be "b become: a" since VA has one-way become:), but the same bug exists in VW (I tried with 2.5 and 7.3)