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:
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:
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:
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
)