Tipos de Escalares Perl

El tipo enumerado svtype enuncia los tipos de escalar:
nereida:~/Lperl-5.9.4> sed -ne '46,64p' sv.h | cat -n
 1  typedef enum {
 2    SVt_NULL,  /* 0  Usado para undef */ 
 3    SVt_IV,    /* 1  Entero */
 4    SVt_NV,    /* 2  Flotante */
 5    SVt_RV,    /* 3  Referencia */
 6    SVt_PV,    /* 4  Cadena */
 7    SVt_PVIV,  /* 5  Cadena o Entero */
 8    SVt_PVNV,  /* 6  Cadena o Flotante */
 9    SVt_PVMG,  /* 7  Objeto o escalar mágico */
10    SVt_PVBM,  /* 8  Como SVt_PVMG: si es cadena usa Boyer-Moore para las búsquedas */
11    SVt_PVGV,  /* 9  Typeglob */
12    SVt_PVLV,  /* 10 Varios tipos con conducta Lvalue */
13    SVt_PVAV,  /* 11 Array */
14    SVt_PVHV,  /* 12 Hash */
15    SVt_PVCV,  /* 13 Código */
16    SVt_PVFM,  /* 14 Formato */
17    SVt_PVIO,  /* 15 Manejador de ficheros */
18    SVt_LAST   /* keep last in enum. used to size arrays */
19  } svtype;
En la jerga, estos tipos son conocidos como IV, NV, PV, etc. Nótese que arrays y hashes son formas de SVs. Existe toda una familia de funciones con nombres SvIV, SvNV, SvPV, etc para leer un escalar (SV) como entero, flotante, cadena, etc. El siguiente código muestra el uso de algunas de estas funciones de acceso:
lhp@nereida:~/Lperl/src/XSUB/inline$ cat -n dump_values.pl
 1  #!/usr/local/bin/perl -w
 2  use strict;
 3  use Inline C => <<'EOC';
 4  void dump_scalar(SV * sv) {
 5
 6    printf("Flotante: %f\n", SvNV(sv));
 7    printf("Entero: %i\n", SvIV(sv));
 8    printf("Cadena: %s\n", SvPV_nolen(sv));
 9    printf("Longitud de la cadena: %i\n", SvCUR(sv));
10    printf("Longitud del espacio asignado para la cadena: %i\n", SvLEN(sv));
11  }
12  EOC
13
14  my $a = "123.53";
15  dump_scalar($a)
El caso de las cadenas es mas complejo: se puede acceder a la longitud de la cadena mediante la macro SvCUR y a la longitud de su buffer mediante la macro SvLEN. Al ejecutar el programa anterior obtenemos la salida:
lhp@nereida:~/Lperl/src/XSUB/inline$ dump_values.pl
Flotante: 123.530000
Entero: 123
Cadena: 123.53
Longitud de la cadena: 6
Longitud del espacio asignado para la cadena: 8

Existe una familia de funciones sv_setiv, sv_setnv, sv_setpv, etc. que permiten la modificación del escalar. Por ejemplo:

lhp@nereida:~/projects/perl/src/XSUB/inline$ cat -n set_values.pl
 1  #!/usr/local/bin/perl -w
 2  use strict;
 3  use Inline C => <<'EOC';
 4  void set_string(SV * sv) {
 5    char h[256];
 6    printf("Input: ");
 7    scanf("%s", &h);
 8    sv_setpv(sv, h);
 9  }
10  EOC
11
12  my $a;
13  set_string($a);
14  print "$a\n";

Casiano Rodríguez León
2010-03-22