Mar Abr 25, 2006 10:45 am
|
 |
slopal
Perlero Nuevo

|
Registrado: 23 Nov 2005
Mensajes: 78
|
|
| Transformar la función split en un bucle |
|
|
Hola.
Necesito transformar la función
| Código: |
| my @loc2_cadena = split //, $cadena; |
en un bucle donde pueda hacer prints... entre medio... de esta manera aunque sea muyyyy larga la cadena, el explorador no me da error de timeout por no escribir nada en la pantalla (el típico mensaje de Loading......).
Seguro que hay una manera muy fácil pero yo estoy un poco espesa......  |
|
|
|

Mar Abr 25, 2006 11:25 am
|
 |
kidd
Creador de Perl en Español

|
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
|
|
|
|
|
Hola:
Lo primero que tienes que hacer es quitar el buffer de STDOUT:
Lo que sucede es que Perl espera a que el buffer llegue a cierto tamaño para desplegarlo, al poner la línea anterior Perl deja de hacer eso y despliega la salida inmediatamente.
Ahora, hacer el split en bucle es muy fácil y sigue una simple lógica, si ves estás asignando el resultado del split a un array, por lo que podemos deducir que el resultado del split es un array, entonces:
| Código: |
use strict;
$|++;
my @loc2_cadena;
for my $line(split //, $cadena){
print "$line\n";
push(@loc2_cadena,$line);
}
exit(1);
|
Toma en cuenta que por hacer el print y después el push el script se puede hacer mucho más lento, pero te permite desplegar línea por línea el resultado, permitiendo al usuario ver lo que está pasando.
Saludos |
|

Mar Abr 25, 2006 2:30 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
|
|
|
|
|
| Código: |
#### Conversión de cadena de caracteres a array
my @loc2_cadena;
{
local $| = 1; # No buffer de salida!
local $\ = "<br>\n"; # Terminación de las líneas
### Barra de actividad
## Pintamos un '>' cada cierto tiempo
## para que el usuario no se aburra
my $puntos_ancho = 100; # Ancho de la barra
my $puntos_largo = length $cadena; # Cantidad de información
my $puntos_paso = int( $puntos_largo / $puntos_ancho );# Cada cuánto tenemos que pintar
# Informamos de lo que va a pasar
print 'Procesando cadena. Espere, por favor...';
print '+', '-' x $puntos_ancho, '+';
# Bucle
{
local $\ = "";
print '+';
for ( my $i = 0; $i < $puntos_largo; $i++ ) {
push @loc2_cadena, substr($cadena,$i,1);
print '>' if ( $i % $puntos_paso ) == 0;
}
}
print '+';
} |
Lo que estamos haciendo es calcular cada cuanto tiempo queremos pintar un '>', de tal forma que al final tenemos una barra de progreso (o de actividad) y el usuario sabe más o menos cuánto le queda para terminar.
Naturalmente, el procesado de la cadena se puede optimizar mucho más, por ejemplo (no probado):
| Código: |
for ( my $i = 0; $i < $puntos_largo; $i += $puntos_paso ) {
push @loc2_cadena, split //, substr( $cadena, $i, $puntos_paso );
print '>';
} |
Aquí, en vez de procesar un carácter cada vez, procesamos conjuntos de caracteres (substr), que son separados (split) e introducidos (push) en el array. Los conjuntos de caracteres tienen un tamaño adecuado a la longitud de la barra de progreso; por eso luego hacemos un simple print del carácter y no como antes, que era cada cierto número de caracteres procesados.
Ultima edición por explorer el Mie Abr 26, 2006 12:09 pm, editado 1 vez |
|

Mie Abr 26, 2006 9:37 am
|
 |
slopal
Perlero Nuevo

|
Registrado: 23 Nov 2005
Mensajes: 78
|
|
|
|
|
¡Hola muchas gracias a los dos!
Una pregunta, ¿qué diferencia hay entre $|++ o $| = 1 ?
Yo al principio del CGI ya tengo puesto el $| = 1, porque me lo recomendó explorer en otra ocasión, para que hiciera prints sin buffers.
¿Es lo mismo? (suponiendo que por defecto $| será igual a 0). |
|
Mie Abr 26, 2006 9:49 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
|
|
|
|
|
$| está puesto por defecto a 0 (ver perlvar).
Tanto una opción como la otra lo ponen a un valor distinto de 0. |
|
Powered by phpBB © 2001, 2005 phpBB Group
|