Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Transformar la función split en un bucle

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Mar Abr 25, 2006 10:45 am
slopal
Perlero Nuevo
Perlero Nuevo
Registrado: 23 Nov 2005
Mensajes: 78
Transformar la función split en un bucle Responder citando

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...... Confused
Mensaje Mar Abr 25, 2006 11:25 am
kidd
Creador de Perl en Español
Creador de Perl en Español
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
Responder citando

Hola:

Lo primero que tienes que hacer es quitar el buffer de STDOUT:

Código:
$|++;


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
Mensaje Mar Abr 25, 2006 2:30 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
Responder citando

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
Mensaje Mie Abr 26, 2006 9:37 am
slopal
Perlero Nuevo
Perlero Nuevo
Registrado: 23 Nov 2005
Mensajes: 78
Responder citando

¡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).
Mensaje Mie Abr 26, 2006 9:49 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
Responder citando

$| está puesto por defecto a 0 (ver perlvar).

Tanto una opción como la otra lo ponen a un valor distinto de 0.
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group