• Publicidad

Variables argumentativas

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

Variables argumentativas

Notapor Leo_Gutierrez » 2008-10-22 23:50 @035

Hola a todos :D

Me surgió la duda de las variables argumentativas, lo que yo quiero hacer es un script que trabaje por consola, o sea hacer algo como esto:
Código: Seleccionar todo
C:\Perl>Code.pl -n

Y que me compare el argumento "-n".

Estoy pensando en usar algo como esto, claro que está mal usado, aun no lo sé implementar:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
if ($ARGV[0] == "-n") {
    print "Normal. \n";
}
if ($ARGV[0] == "-o") {
    print "Otro\n";
}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Si alguien me pudiera orientar por favor.
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Publicidad

Notapor explorer » 2008-10-23 04:24 @225

Las comparaciones de cadenas de caracteres se hace con otros operadores lógicos: eq, ne, lt, gt y cmp.

En tu caso, sería así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
if ($ARGV[0] eq '-n') {
    print "Normal. \n";
}
elsif ($ARGV[0] eq '-o') {
    print "Otro\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Más información en perlop, Operadores relacionales.

Otra opción es usar la opción '-s', que ofrece un rudimentario procesado de los argumentos. Así, con este programa:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -s
print "n:[$n]\n";
print "o:[$o]\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
y lo ejecutamos:
Código: Seleccionar todo
explorer@joaquin:~/Documents/Desarrollo> ./programa.pl -n=hhh -o
n:[hhh]
o:[1]
Fíjate que Perl asigna automáticamente el valor de las opciones que se le pasen.

Bueno, en caso de que uses strict (que naturalmente deberías usarlo), el programa quedaría así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -s
use strict;
use warnings;

our $n;
our $o;

print "n:[$n]\n";
print "o:[$o]\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
El único cambio importante es agregar la declaración de las variables $n y $o, como globales a la aplicación.

Más información en perlrun.

Y, finalmente, si necesitas más potencia, mira en CPAN por alguno de los muchos módulos de la rama Getopt. Los más famosos son Getopt::Std (incluido de base con Perl), Getopt::Simple, Getopt::Long y curiosos como Getopt::Auto y Getopt::Lazy.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Leo_Gutierrez » 2008-10-23 23:58 @040

Muchas gracias por responder, explorer, me ayudó mucho tu respuesta, con lo que aprendí de lo que pusiste, y de el tutorial de Despliegue de fecha, hice este script, en necesidad de que no me gusta el comando DATE /T de Windows :

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
if(!$ARGV[0]) {
print "Fecha.pl\n\n";
print "Modo de uso : \n";
print "fecha.pl [/time] [/mday] [/month] [/year] [/wday] [/yday]\n";
print "/time  : Muestra la hora actual del sistema.\n";
print "/mday  : Muestra el dia del mes.\n";
print "/month : Muestra el nombre del mes actual.\n";
print "/year  : Muestra el año en curso.\n";
print "/wday  : Muestra el dia de la semana.\n";
print "/yday  : Muestra el numero del dia del año.\n";
exit;
}
if ($ARGV[0] eq '/time' || $ARGV[0] eq '/TIME') {
print "$hour:$min:$sec";
exit;
}
if ($ARGV[0] eq '/mday' || $ARGV[0] eq '/MDAY') {
print "$mday";
exit;
}
if ($ARGV[0] eq '/month' || $ARGV[0] eq '/MONTH') {
my $number = $mon;
for (; $number < 12; $number++) {
if ($number == 1) {print "Enero\n";}
if ($number == 2) {print "Febrero\n";}
if ($number == 3) {print "Marzo\n";}
if ($number == 4) {print "Abril\n";}
if ($number == 4) {print "Mayo\n";}
if ($number == 5) {print "Junio\n";}
if ($number == 6) {print "Julio\n";}
if ($number == 7) {print "Agosto\n";}
if ($number == <img src="http://perlenespanol.com/foro/images/smilies/icon_cool.gif" alt="8)" title="Cool" /> {print "Septiembre\n";}
if ($number == 9) {print "Octubre\n";}
if ($number == 10) {print "Noviembre\n";}
if ($number == 11) {print "Diciembre\n";}
exit;
}
}
if ($ARGV[0] eq '/year' || $ARGV[0] eq '/YEAR') {
system("echo %date:~6,4%");
exit;
}
if ($ARGV[0] eq '/wday' || $ARGV[0] eq '/WDAY') {
my $number = $wday;
if ($number == 1) {print "Lunes\n";}
if ($number == 2) {print "Martes\n";}
if ($number == 3) {print "Miercoles\n";}
if ($number == 4) {print "Jueves\n";}
if ($number == 5) {print "Viernes\n";}
if ($number == 6) {print "Sabado\n";}
if ($number == 0) {print "Domingo\n";}
exit;
}
if ($ARGV[0] eq '/yday' || $ARGV[0] eq '/YDAY') {
print "$yday\n";
exit;
}
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


Cualquier sugerencia es bien recibida.
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Notapor explorer » 2008-10-24 04:55 @247

No está mal el código, pero quiero que te fijes en lo siguiente:

* El uso de array ahorra muchas líneas. Fíjate en tus líneas que hay varios print() que hacen casi lo mismo. Me refiero a los de los meses y los días
* La comparación $ARGV[0] eq '/time' || $ARGV[0] eq '/TIME' es un caso muy bueno para reducirlo: a una sola comparación, ya que la diferencia es solo si está en mayúsculas o minúsculas
* La impresión de horas, minutos y segundos, cuando no tienen dos dígitos, queda descompensada
* No sé porque llamas a system() para saber la cifra del año si ya te lo da localtime()

Fíjate en esta variación:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        1 #!/usr/bin/perl -l
        2 #use strict;
        3 #use warnings;
        4 #use diagnostics;
        5
        6 my @meses = qw( Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre Noviembre Diciembre );
        7 my @dias  = qw( Domingo Lunes Martes Miércoles Jueves Viernes Sábado );
        8
        9 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime;
       10 $year += 1900;
       11 $mon  += 1;
       12
       13 if (!@ARGV) {
       14     print <<END_OF_INFO;
       15 Fecha.pl
       16
       17 Modo de uso :
       18 fecha.pl [/time|/mday|/month|/year|/wday|/yday]
       19     /time   : Muestra la hora actual del sistema
       20     /mday   : Muestra el día del mes
       21     /month  : Muestra el nombre del mes actual
       22     /year   : Muestra el año en curso
       23     /wday   : Muestra el día de la semana
       24     /yday   : Muestra el número del día del año
       25 END_OF_INFO
       26 }
       27 elsif (lc($ARGV[0]) eq '/time') {
       28     printf "%02d:%02d:%02d\n", $hour, $min, $sec;
       29 }
       30 elsif (lc($ARGV[0]) eq '/mday') {
       31     print $mday;
       32 }
       33 elsif (lc($ARGV[0]) eq '/month') {
       34     print $meses[$mon-1];       # Los array se basan en 0
       35 }
       36 elsif (lc($ARGV[0]) eq '/year') {
       37     print $year;
       38 }
       39 elsif (lc($ARGV[0]) eq '/wday') {
       40     print $dias[$wday];         # $wday ya está basado en 0
       41 }
       42 elsif (lc($ARGV[0]) eq '/yday') {
       43     print $yday;
       44 }
       45 else {
       46     print 'Argumento desconocido. Ejecute el programa sin argumentos para ver la ayuda.';
       47 }
       48
       49 __END__
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Comentarios, según la línea
  • 1.- Debido a que la mayor parte de las salidas del programa consisten en un print() de un texto terminado en un carácter de avance de línea, ponemos la opción '-l' para ahorrarnos poner ese fin de línea (somos muy vagos...)
  • 6 y 7.- Guardamos la información en forma de array, que usaremos más tarde
  • 9.- Quitamos la variable $istdst porque no la usamos en el resto del programa. Esto lo podemos hacer porque es la última de la lista de variables
  • 10 y 11.- Ajustamos los valores reales de año y mes
  • 14 a 25.- Sustituimos los print() del mensaje de información por uno solo, con la técnica de Here-doc
  • 27 y siguientes.- Las comparaciones son así: pasamos el parámetro pasado por el usuario a minúsculas con la ayuda de la función lc(), y así solo tenemos que hacer una comparación
  • 27 y siguientes.- Ponemos los 'if' en cascada, y nos ahorramos los exit(), ya que solo se ejecutará uno solo de los 'if'.
  • 28.- Como las cifras de horas, minutos y segundos pueden tener un solo dígito, los formateamos con printf()
  • 34 y 40.- El uso de array ahorra mucho código. Accedemos a la información que queremos usando los valores de mes y día como índices dentro de los array
  • 45.- En caso de que el usuario pase un argumento desconocido, se lo decimos.
De todas maneras, tu programa está muy bien, y funciona. Te animo a que sigas practicando. Con la experiencia descubrirás nuevas posibilidades, y también ha descubrir y corregir errores.

Un ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
#use strict;
#use warnings;
#use diagnostics;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime(time);
$year += 1900;
$mon  += 1;

my @meses    = qw( enero febrero marzo abril mayo junio
                   julio agosto septiembre octubre noviembre diciembre
             );
my @dias     = qw( domingo lunes martes miércoles jueves viernes sábado );
my %comandos =   (
     '/time' =>  [ 'Muestra la hora actual del sistema', sprintf "%02d:%02d:%02d", $hour, $min, $sec ],
     '/mday' =>  [ 'Muestra el día del mes'            , $mday                                       ],
     '/month'=>  [ 'Muestra el nombre del mes actual'  , $meses[$mon-1]                              ],
     '/year' =>  [ 'Muestra el año en curso'           , $year                                       ],
     '/wday' =>  [ 'Muestra el día de la semana'       , $dias[$wday]                                ],
     '/yday' =>  [ 'Muestra el número del día del año' , $yday                                       ],
             );

if (@ARGV) {
    my $arg = lc $ARGV[0];
    if ($comandos{$arg}) {
        print $comandos{$arg}[1], "\n";
        exit 0;                         # Ha ido bien
    }
}

print 'Modo de uso: fecha.pl [' . join('|', map {"[$_]"} sort keys %comandos) . "]\n";

for my $arg (sort keys %comandos) {
    printf "%10s : %s\n", $arg, $comandos{$arg}[0];
}
exit 1;                                 # Ha ido mal

__END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Aquí usamos el uso de un hash de array para ayudar a almacenar tanto los mensajes de ayuda como el resultado de cada uno.

E incluso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
#use strict;
#use warnings;
#use diagnostics;

use POSIX qw(strftime locale_h);

setlocale(LC_TIME, "es_ES");

my %comandos =   (
     '/time' =>  [ '%T', 'Muestra la hora actual del sistema' ],
     '/mday' =>  [ '%d', 'Muestra el día del mes'             ],
     '/month'=>  [ '%B', 'Muestra el nombre del mes actual'   ],
     '/year' =>  [ '%Y', 'Muestra el año en curso'            ],
     '/wday' =>  [ '%A', 'Muestra el día de la semana'        ],
     '/yday' =>  [ '%j', 'Muestra el número del día del año'  ],
             );

if (@ARGV) {
    my $arg = lc $ARGV[0];
    if ($comandos{$arg}) {
        print strftime($comandos{$arg}[0], localtime), "\n";
        exit 0;                         # Ha ido bien
    }
}

print 'Modo de uso: fecha.pl [' . join('|', map {"[$_]"} sort keys %comandos) . "]\n";

for my $arg (sort keys %comandos) {
    printf "%10s : %s\n", $arg, $comandos{$arg}[1];
}
exit 1;                                 # Ha ido mal

__END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Aquí usamos la función strftime() del módulo POSIX para que se encargue de todo el trabajo de cálculo de fechas y nombres de días y meses. Y con el añadido de 'locale_h' tenemos a nuestra disposición los 'locales' del sistema: con solo cambiar "es_ES" por "fr_FR" nuestro programa sacará las fechas en Francés:
Código: Seleccionar todo
explorer@joaquin:~/Documents/Desarrollo> fecha.pl /wday
vendredi
Con "da_DK", en danés:
Código: Seleccionar todo
explorer@joaquin:~/Documents/Desarrollo> fecha.pl /wday
fredag
Y cambiándolo por "ja_JP.eucjp", en japonés:
Código: Seleccionar todo
explorer@joaquin:~/Documents/Desarrollo> fecha.pl /wday
金曜日
(naturalmente, depende de que en tu sistema tenga soporte de japonés :) )
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Leo_Gutierrez » 2008-10-24 11:04 @503

En mi código llamé a system() porque no sabía cómo sacar solo el año, además de que me gusta también BATCH, pero viendo tu código, también lo podría implementar así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime;
print "". $year+1900;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No tenía idea de la función qw(), ya me quedó un poco más clara.

Igual me gustó la forma de cambiar el $ARGV[0] a minúsculas y luego hacer la comparación. :D

No tenía idea de esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print <<END_OF_INFO;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Resulta muy útil, me ahorra los print().

El primer código tuyo lo entendí, los demás requieren un poco más de estudio de mi parte :)

Me queda una pregunta, en tus códigos pones al principio:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#use strict;
#use warnings;
#use diagnostics;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Realmente esto si corre?, o sea, ¿sí se ejecuta?, ¿o son solo comentarios?

Saludos.
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Notapor Leo_Gutierrez » 2008-10-24 12:29 @562

Ahora hice este otro script, para contar las líneas de un archivo, llamando la función por consola:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
if(!$ARGV[0]) {
print <<END_OF_INFO;
contlin.pl     :     Cuenta el número de líneas de un archivo.

Modo de uso :
contlin.pl Archivo.ext

por Leonardo Gutierrez R.
END_OF_INFO
exit;
}
open(TEXTO, "$ARGV[0]") or die "El archivo no existe, o no se pudo abrir.\n";
my @lineas = <TEXTO>;
print "" . $#lineas+1;
close (TEXTO);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Aprendí a usar un poco el "die".

:D
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Notapor explorer » 2008-10-24 18:40 @819

Del
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print "". $year+1900;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
lo puedes dejar en
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print $year+1900;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Por eso en el primer programa, hago un
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$year += 1900;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
para dejarlo ya a su cifra correcta y no preocuparme luego más.

qw() no es en sí una 'función', sino una forma de entrecomillar. qw() sirve para crear listas de palabras. En lugar de escribir
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@x = ('Hola', 32, 'abuela', 15);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
podemos escribir, con menos pulsaciones:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@x = qw( Hola 32 abuela 15);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En cuanto a las 3 líneas, sí, son comentarios. El resumen es: hay que descomentarlas mientras estamos creando el programa, pues Perl nos ayudará a encontrar los problemas. Yo suelo usarlas siempre.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
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 0 invitados

cron