lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ perl -ne '$x = 1 if /struct sv/; print if $x; exit if $x && /}/' sv.h struct STRUCT_SV { /* struct sv { */ void* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ };El módulo Devel::Peek permite acceder a parte de la información en dicha estructura de datos desde un programa Perl:
lhp@nereida:~/Lperl/src/XSUB/Example$ perl -MDevel::Peek -de 0 Loading DB routines from perl5db.pl version 1.28 main::(-e:1): 0 DB<1> $a = 5 DB<2> Dump $a SV = IV(0x83833b8) at 0x8437350 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 5
El tipo SV es usado para representar un escalar.
La dirección entre paréntesis se refiere al lugar en el que se encuentra almacenado
el valor, el cual es apuntado por el campo sv_any .
Se nos informa que
contiene un tipo de datos entero: las siglas IV vienen de Integer Value.
La información proveída indica que $a
esta en la dirección 0x8437350
.
El campo REFCNT ( sv_refcnt ) de la estructura lleva el numero de referencias al valor. Es usado por el sistema de gestión de memoria de Perl: si el contador de referencia de un valor vale cero la memoria ocupada por dicho valor puede ser liberada. En efecto, si a continuación hacemos:
DB<3> $b = \$a DB<4> Dump $a SV = IV(0x83833b8) at 0x8437350 REFCNT = 2 FLAGS = (IOK,pIOK) IV = 5Observamos que
REFCNT
pasa a valer 2 indicando ahora que dicho valor esta
siendo referenciado mediante dos ligaduras: a través de $a
e indirectamente
a través de $b
.
Perl lleva la información sobre el estado de uso de una variable en un campo FLAGS . El módulo Devel::Peek nos permite observar el estado de las flags o banderas.
Después de hacer la asignación $a = 5
vimos
que el campo sv_any
apuntaba a la estructura de
datos de tipo IV que contiene la información necesaria y que
las banderas IOK
y pIOK
están activas.
Continuando nuestra sesión, asignemos una cadena a $a
:
DB<6> $a = "hola" DB<7> Dump $a SV = PVIV(0x8151e80) at 0x8437350 REFCNT = 2 FLAGS = (POK,pPOK) IV = 5 PV = 0x824d750 "hola"\0 CUR = 4 LEN = 8
Después de la asignación $a = "Hola"
los flags cambian a FLAGS = (POK,pPOK)
indicando que ahora
la interpretación válida del escalar es como cadena.
No sólo cambia la dirección apuntada por el campo sv_any
sino
que también lo hace el tipo de lo apuntado: PVIV . El tipo
PVIV
indica que el valor puede ser una cadena o un número.
El tipo PVIV
se implanta en el intérprete mediante
una estructura de datos con nombre xpviv
:
lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ perl -ne '$x = 1 if /struct xpviv/; print if $x; exit if $x && /}/' sv.h struct xpviv { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ IV xiv_iv; /* integer value or pv offset */ };
El campo CUR (xpv_cur
) contiene la longitud de la cadena mientras
que el campo LEN (xpv_len
) informa de la cantidad de memoria reservada
para la misma.