It's because what Eliya said isn't completely true. «$x{a} &&= 1;» isn't exactly equivalent to «$x{a} = $x{a} && 1;». Specifically, «$x{a}» is never assigned to itself. What really happens:
- The RHS of the assignment (1) is evaluated.
- The LHS of the assignment ($x{a}) is evaluated in lvalue context (which vivifies the hash element). [FETCH]
- If the scalar from the LHS is false,
- The scalar from the RHS is assigned to the scalar returned by the LHS. [STORE]
Notice how the store is conditional? The autovivification actually occurs on fetch.
The reason your tie code doesn't behave like the non-tie code is that you didn't autovivify the inner hash on fetch like the non-tie code does (step 2). But that's excusable -- I don't know if you can even tell you were called in lvalue context.