• Publicidad

Transformar la función split en un bucle

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Transformar la función split en un bucle

Notapor slopal » 2006-04-25 11:45 @531

Hola.

Necesito transformar la función
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @loc2_cadena = split //, $cadena;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

en un bucle donde pueda hacer print()... 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... :?
slopal
Perlero nuevo
Perlero nuevo
 
Mensajes: 78
Registrado: 2005-11-23 11:41 @528

Publicidad

Notapor kidd » 2006-04-25 12:25 @559

Hola:

Lo primero que tienes que hacer es quitar el búfer de STDOUT:

$|++;

Lo que sucede es que Perl espera a que el búfer 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:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use strict;
  2. $|++;
  3.  
  4. my @loc2_cadena;
  5.  
  6. for my $line ( split //, $cadena ) {
  7.     print "$line\n";
  8.     push( @loc2_cadena, $line );
  9. }
  10.  
  11. exit(1);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Notapor explorer » 2006-04-25 15:30 @687

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #### Conversión de cadena de caracteres a array
  2. my @loc2_cadena;
  3. {
  4.     local $| = 1;                                           # ¡No búfer de salida!
  5.     local $\ = "<br>\n";                                    # Terminación de las líneas
  6.  
  7.     ### Barra de actividad
  8.     ## Pintamos un '>' cada cierto tiempo
  9.     ## para que el usuario no se aburra
  10.     my $puntos_ancho = 100;                                 # Ancho de la barra
  11.     my $puntos_largo = length $cadena;                      # Cantidad de información
  12.     my $puntos_paso  = int( $puntos_largo / $puntos_ancho );# Cada cuánto tenemos que pintar
  13.  
  14.     # Informamos de lo que va a pasar
  15.     print 'Procesando cadena. Espere, por favor...';
  16.     print '+', '-' x $puntos_ancho, '+';
  17.  
  18.     # Bucle
  19.     {
  20.         local $\ = "";
  21.         print '+';
  22.         for ( my $i = 0; $i < $puntos_largo; $i++ ) {
  23.  
  24.             push @loc2_cadena, substr($cadena,$i,1);
  25.  
  26.             print '>' if ( $i % $puntos_paso ) == 0;
  27.         }
  28.     }
  29.  
  30.     print '+';
  31. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Lo que estamos haciendo es calcular cada cuánto 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):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for ( my $i = 0; $i < $puntos_largo; $i += $puntos_paso ) {
  2.  
  3.     push @loc2_cadena, split //, substr( $cadena, $i, $puntos_paso );
  4.  
  5.     print '>';
  6. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
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.
Última edición por explorer el 2006-04-26 13:09 @590, editado 1 vez en total
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor slopal » 2006-04-26 10:37 @484

¡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 print() sin búfer.

¿Es lo mismo? (suponiendo que por defecto $| será igual a 0).
slopal
Perlero nuevo
Perlero nuevo
 
Mensajes: 78
Registrado: 2005-11-23 11:41 @528

Notapor explorer » 2006-04-26 10:49 @492

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

Tanto una opción como la otra lo ponen a un valor distinto de 0.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 22 invitados