Search code examples
perlperlguts

Are all references live in scalars? even explicit ones?


For instance:

use strict;
use warnings;
use Devel::Peek;

Dump({});

Would print the following:

SV = IV(0x170fc98) at 0x170fca8
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x170fa68
  SV = PVHV(0x1715970) at 0x170fa68
    REFCNT = 1
    FLAGS = (SHAREKEYS)
    ARRAY = 0x0
    KEYS = 0
    FILL = 0
    MAX = 7
    RITER = -1
    EITER = 0x0

it seems like SV = IV(0x170fc98) at 0x170fca8 (a numerical, IV, scalar) references the PVHV (hash) SV = PVHV(0x1715970) at 0x170fa68

I was expecting something like:

  SV = PVHV(0x1715970) at 0x170fa68
    REFCNT = 1
    FLAGS = (SHAREKEYS)
    ARRAY = 0x0
    KEYS = 0
    FILL = 0
    MAX = 7
    RITER = -1
    EITER = 0x0

Solution

  • Each data type in Perl has a common “header” of data that supplies reference counting, etc. The flags in this header determine what type it actually is (e.g. a PVHV). So internally a %hash is a PVHV. The header is followed by other hash-specific fields.

    Now what is a $reference = \%hash? A reference is a scalar containing a pointer to another data type. This is implemented as the integer field in an IV, but the ROK flag is set to show that the data isn't an integer but a pointer.

    You can only pass scalars to a Perl subroutine, therefore you can only pass a hash reference, not a hash itself to Dump. As Dump prints out whatever scalar you provide, the enclosing reference is also shown.

    To understand internal data types in Perl better, I recommend the Illustrated Perl Guts.