2010-05-09 7 views
6

Estoy tratando de obtener un bloque de código en una línea. Necesito una manera de obtener la cantidad de elementos en una lista. Mi código actualmente se ve así:Perl - Cómo obtener la cantidad de elementos en una matriz anónima, para recortar de forma concisa nombres de ruta

# Include the lib directory several levels up from this directory 
my @ary = split('/', $Bin); 
my @ary = @ary[0 .. $#ary-4]; 
my $res = join '/',@ary; 
lib->import($res.'/lib'); 

Eso está muy bien, pero me gustaría hacer que una línea, algo como esto:

lib->import(join('/', ((split('/', $Bin)) [0 .. $#ary-4])) ); 

Pero, por supuesto, la sintaxis $#ary no tiene sentido en la línea anterior .

¿Hay forma equivalente de obtener la cantidad de elementos en una lista anónima?

Gracias!

PS: La razón de la consolidación de esto es que será en la cabecera de un grupo de scripts de Perl que son accesorias a la aplicación principal, y yo quiero que esto poco encantamiento para ser más corta & prueba de pasta.

Gracias a todos

No parece ser una abreviatura para el número de elementos de una lista anónima . Eso parece un descuido. Sin embargo, las alternativas sugeridas fueron todas buenas.

voy con:

lib->import(join('/', splice(@{[split('/', $Bin)]}, 0, -4)).'/lib'); 

Pero Éter sugerido lo siguiente, que es mucho más correcto y portátil:

my $lib = File::Spec->catfile(
       realpath(File::Spec->catfile($FindBin::Bin, ('..') x 4)), 
       'lib'); 
lib->import($lib); 
+2

Por qué estás tratando de obtener un bloque de código a una sola línea? SI es solo para cortar y pegar, ese es tu problema. En lugar de eso, crea una biblioteca que haga lo que necesites para que no tengas que cortar y pegar. Es por eso que existen subrutinas. :) –

+0

No se puede poner en una lib, porque esta es la línea de código que establece el directorio de inclusión para las libs personalizadas. Además, no quiero :) Pero creo que es una pregunta interesante por sí misma de todos modos. – NXT

Respuesta

3
lib->import(join('/', splice(@{[split('/', $bin)]}, 0, -4)).'/lib'); 
+0

Editar, disculpa por mi estúpido comentario, leí tu código incorrectamente. Esta es la respuesta. – NXT

+0

Esto debería funcionar como está, empalme con tres argumentos es empalme (matriz, desplazamiento, longitud) - el 0 especifica el comienzo, el -4 significa (longitud de la matriz-4). Alguien más mencionó que 0 .. -4 es legal. Si bien es cierto, usted necesita considerar lo que eso significa perl: 'contar desde 0 hasta -4 '(no muy significativo). – pdehaan

2

comprobar la función splice.

+0

Gracias, pero no funciona. 'splice (split ('/', $ Bin), -4)' da un error: el tipo de arg 1 para empalmar debe ser una matriz (no dividida). Splice parece querer una matriz ACTUAL. – NXT

+0

Un truco: puede usar @ {[división ...]}. Efectivamente, creará una matriz, tomará su referencia y luego la desreferenciará. Además, tenga en cuenta: necesita desplazamiento y longitud en el empalme: 0, -4. –

+0

@IK: Sí, incluyendo tanto el desplazamiento como la longitud fue mi problema final. – NXT

1

Puede manipular una matriz (como eliminar los últimos n elementos) con la función splice, pero también puede generar una porción de una matriz usando un índice negativo (donde -1 significa el último elemento, -2 significa la penúltimo, etc.): por ejemplo @list = @arr[0 .. -4] es legal.

Sin embargo,, usted parece estar pasando por un montón de backflips manipulando estas listas cuando lo que parece que falta es la ubicación de un directorio lib. ¿No sería más fácil proporcionar un argumento -I al ejecutable de Perl, o usar $FindBin::Bin y File::Spec->catfile para ubicar un directorio relativo a la ubicación del script?

use strict; 
use warnings; 

use Cwd 'realpath'; 
use File::Spec; 
use FindBin; 

# get current bin 
# go 4 dirs up, 
# canonicalize it, 
# add /lib to the end 
# and then "use" it 

my $lib = File::Spec->catfile(
       realpath(File::Spec->catfile($FindBin::Bin, ('..') x 4)), 
       'lib'); 
lib->import($lib); 
+0

Gracias. Vea otra respuesta sobre por qué el empalme no funciona. He probado índices negativos en la porción como se muestra, pero no obtengo ninguna salida. Ya estoy usando FindBin :: Bin para obtener el guión dir, y File :: Spec no parece hacer nada útil para mí (sería bueno si updir() tomara un argumento para que pudieras subir a más de un directorio . – NXT

+0

@NXT: la manera "habitual" de subir directorios en el sistema de archivos es mediante el uso de 'realpath' de Cwd para canonicalizar una ruta usando' ..'. – Ether

+0

gracias, lo entiendo ahora. No lo sabía. En este caso tomaré concisión sobre lo correcto. Pero estoy tomando nota de esto para el futuro. – NXT

Cuestiones relacionadas