in reply to Why do $x="$h->{foo}" and $x=$h->{foo} have different effects (as reported by Devel::Peek)?

I'm no expert on Perl internals, so take what I say with some salt.

That said, I think I have an idea about what's going on here. A scalar in Perl can have a number or a string in it, and Perl will convert back and forth between them as necessary. The structure that Perl uses for a scalar has a pointer for a string and a pointer for a number, and it has flags to show which are valid representations of this scalar. That way, if you stored a string, and it converted it to a number, it can hold both of them and know that they're both valid and not have to do the conversion again. When you store a string or a number, the other pointer is marked as invalid but not actually changed.

You can see this in your tests. The pointers to values are IV and PV for numbers and strings, respectively. The flags for their validity are p?IOK and p?POK.

Lets look at the test.

  1. You create a string and a number.
  2. You set a new $x to the string. That sets its PV.
  3. You set $x to the number. That sets the IV and invalidates the PV.
  4. You peek at $x and see it has both IV and PV set to unrelated values (number and string), but only one is valid—IOK (the number).
  5. You use $x as a string. Perl converts the number to a string and stores it as the PV and flags the string representation as valid.
  6. You peek again and see IV and PV both as 5-ish and both have flags to show them as valid (POK and IOK).
  7. You set $x to the string value. The IV remains 5, but the PV changes to the new value. The IOK flag is removed, so the stale number (5) won't be used.
  8. You set $x to the number. The PV remains the string, and the IV "changes" to the value it had anyway. The flags get flipped so that IOK is true and POK is false. Now $x can be used as-is as a number, but the string representation is invalid.
  9. You peek again. IV = 5, PV = abc, but only IOK.
  10. You assign to $x the number interpolated into a string. That changes the number to a string and gives the string value to $x. The PV is set to "5". IV is coincidentally also 5, but it's not flagged as valid because a string was just assigned.
  11. One last peek to show what I just described.

The only time this string/numeric duality ever bit me was the time I documented in Strings and numbers: losing memory and mind.. Long story short, having both representations of something laying around takes a little extra memory, and I had a lot of scalars with both values set.

  • Comment on Re: Why do $x="$h->{foo}" and $x=$h->{foo} have different effects (as reported by Devel::Peek)?
  • Select or Download Code