AV
) se guarda en un nodo de tipo XPVAV
:
lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ grep 'typedef.*\ <AV;' *.h perl.h:typedef struct av AV; lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ perl -ne \ '$x = 1 if /struct av/; print if $x; exit if $x && /}/' sv.h struct av { XPVAV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ };
El tipo XPVAV
tiene la siguiente estructura:
lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ grep 'typedef .*XPVAV' *.h perl.h:typedef struct xpvav XPVAV; lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ perl -ne \ '$x = 1 if /struct xpvav {/; print if $x; exit if $x && /}/' av.h struct xpvav { char* xav_array; /* pointer to first array element */ SSize_t xav_fill; /* Index of last element present */ SSize_t xav_max; /* max index for which array has space */ IV xof_off; /* ptr is incremented by offset */ NV xnv_nv; /* numeric value, if any */ MAGIC* xmg_magic; /* magic for scalar array */ HV* xmg_stash; /* class package */ SV** xav_alloc; /* pointer to beginning of C array of SVs */ SV* xav_arylen; U8 xav_flags; };El campo
xav_alloc
apunta al primer elemento del array C
asignado mientras que el campo xav_array
apunta al primer elemento de la lista de valores escalares (no
siempre son iguales).
El campo xav_arylen
apunta al valor escalar mágico que
se corresponde con el constructo Perl $#array
.
lhp@nereida:~/Lperl/src/XSUB/cpanexamples/String-Index-0.02$ perl -MDevel::Peek -de 0 Loading DB routines from perl5db.pl version 1.28 main::(-e:1): 0 DB<1> @a = qw/primero segundo/ DB<2> Dump(\@a) SV = RV(0x817e1f0) at 0x844dc2c REFCNT = 1 FLAGS = (ROK) RV = 0x844daa0 SV = PVAV(0x8480e68) at 0x844daa0 REFCNT = 2 FLAGS = () IV = 0 NV = 0 ARRAY = 0x816f8d0 FILL = 1 MAX = 3 ARYLEN = 0x0 FLAGS = (REAL) Elt No. 0 SV = PV(0x8443440) at 0x81531b0 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x8475990 "primero"\0 CUR = 7 LEN = 8 Elt No. 1 SV = PV(0x83c975c) at 0x81526b8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x83c9c48 "segundo"\0 CUR = 7 LEN = 8El campo
ARYLEN
es inicializado si usamos $#a
.
DB<3> p "$#a\n" 1 DB<4> Dump(\@a) SV = RV(0x817e200) at 0x844dc2c REFCNT = 1 # esta información es relativa ala argumento de Dump: \@a FLAGS = (ROK) RV = 0x844daa0 SV = PVAV(0x8480e68) at 0x844daa0 REFCNT = 2 # Es referenciado por @a y por el argumento de Dump FLAGS = () IV = 0 NV = 0 ARRAY = 0x816f8d0 FILL = 1 MAX = 3 ARYLEN = 0x844daf4 FLAGS = (REAL) Elt No. 0 SV = PV(0x8443440) at 0x81531b0 REFCNT = 1 # Solo una referencia a este valor FLAGS = (POK,pPOK) # Indican que se esta usando como cadena PV = 0x8475990 "primero"\0 CUR = 7 # Longitud de la cadena LEN = 8 # Cantidad de memoria asignada Elt No. 1 SV = PV(0x83c975c) at 0x81526b8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x83c9c48 "segundo"\0 CUR = 7 LEN = 8Si extraemos la cabecera de la lista:
DB<5> $a = shift @aCambia el campo
ARRAY
que para apuntar al nuevo
comienzo de la lista se desplaza desde 0x816f8d0
a 0x816f8d4
(un puntero mas).
También cambian FILL
(índice del último elemento, que pasa de 1 a 0)
y MAX
(máximo índice para el cual se dispone de espacio, ahora pasa
a ser 2).
DB<6> Dump(\@a) SV = RV(0x817e210) at 0x844dc2c REFCNT = 1 FLAGS = (ROK) RV = 0x844daa0 SV = PVAV(0x8480e68) at 0x844daa0 REFCNT = 2 FLAGS = () IV = 0 NV = 0 ARRAY = 0x816f8d4 (offset=1) ALLOC = 0x816f8d0 FILL = 0 MAX = 2 ARYLEN = 0x844daf4 FLAGS = (REAL) Elt No. 0 SV = PV(0x83c975c) at 0x81526b8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x83c9c48 "segundo"\0 CUR = 7 LEN = 8Introduzcamos dos nuevos elementos:
DB<7> $a = push @a, qw/tercero cuarto quinto/Ahora
ARRAY
es 0x816f3a0
. El array ha sido reubicado.
Puesto que hay cuatro elementos
FILL
es 3.
Se ha solicitado mas memoria ya que
MAX
es 11.
DB<8> Dump(\@a) SV = RV(0x817e228) at 0x844d6d4 REFCNT = 1 FLAGS = (ROK) RV = 0x844daa0 SV = PVAV(0x8480e68) at 0x844daa0 REFCNT = 2 FLAGS = () IV = 0 NV = 0 ARRAY = 0x816f3a0 FILL = 3 MAX = 11 ARYLEN = 0x844daf4 FLAGS = (REAL) Elt No. 0 SV = PV(0x83c975c) at 0x81526b8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x83c9c48 "segundo"\0 CUR = 7 LEN = 8 Elt No. 1 SV = PV(0x844365c) at 0x844d7a0 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x83f5a28 "tercero"\0 CUR = 7 LEN = 8 Elt No. 2 SV = PV(0x8443680) at 0x844d644 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x824d868 "cuarto"\0 CUR = 6 LEN = 8 Elt No. 3 SV = PV(0x8443608) at 0x844d5d8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x83bc2a8 "quinto"\0 CUR = 6 LEN = 8
Casiano Rodríguez León