2011-12-09 10 views
14

Quiero crear una referencia a una matriz obtenida por una división en Perl. estoy pensando algo como:¿Cómo hacer referencia a una expresión dividida en Perl?

my $test = \split(/,/, 'a,b,c,d,e'); 

foreach $k (@$test) { 
    print "k is $k\n"; 
} 

Pero se queja de que con Not an ARRAY reference at c:\temp\test.pl line 3. He intentado algunas otras alternativas, todas sin éxito.

Respuesta

31

Antecedentes explicación:

split, al igual que otras funciones, devuelve una lista. No puede tomar una referencia a una lista. Sin embargo, si aplica el operador de referencia a una lista, se aplica a todos sus miembros. Por ejemplo:

use Data::Dumper; 

my @x = \('a' .. 'c'); 

print Dumper \@x 

Salida:

$VAR1 = [ 
      \'a', 
      \'b', 
      \'c' 
     ];

Por lo tanto, cuando se escribe my $test = \split(/,/, 'a,b,c,d,e');, se obtiene una referencia al último elemento de la lista devuelta (ver, por ejemplo, What’s the difference between a list and an array?). Su situación es similar a:

A pesar de que parece que tiene una lista en el lado derecho, Perl realmente ve un montón de escalares separados por una coma:

my $scalar = ('dog', 'cat', 'bird'); # $scalar gets bird 

Puesto que usted Al asignar a un escalar, el lado derecho está en contexto escalar. El operador de coma (sí, es un operador!) En contexto escalar evalúa su lado izquierdo, descarta el resultado, evalúa su lado derecho y devuelve el resultado. En efecto, ese look de lista asigna a $ escalar su valor más a la derecha. Muchas personas estropear esto becuase que elijan una lista-Lookalike cuyo último elemento es también el recuento que esperan:

my $scalar = (1, 2, 3); # $scalar gets 3, accidentally 

En su caso, lo que se obtiene en el lado derecho es una lista de referencias a los elementos de la lista devuelta por split, y el último elemento de esa lista termina en $test. Primero necesita construir una matriz a partir de esos valores de retorno y tomar una referencia a eso. Puede hacer que una sola declaración de formar un conjunto anónimo y almacenar la referencia a que en $test:

my $test = [ split(/,/, 'a,b,c,d,e') ]; 
+0

¡Es por eso que amo SO! Muchas gracias por su minuciosa, paciente y muy clara explicación. Está completamente claro ahora, he aprendido mucho hoy. ¡Gracias! –

19

Envuelve el comando split entre corchetes para hacer una referencia anónima.

my $test = [ split(/,/, 'a,b,c,d,e') ]; 
+0

Gracias Yo era un poco engañar con los ejemplos de barra invertida en mi libro Perl. –

+1

¿Es esto tan eficiente como almacenar el resultado dividido en var '@ splitResult', y luego tomar una referencia a esa var con' $ arrayRef = \ @ splitResult'? ¿O se está inicializando la matriz dos veces? Una vez durante la división y nuevamente para inicializar la matriz anónima ref. – Despertar

Cuestiones relacionadas