En Perl, por defecto(*), no soporta firmas en la definición de las subrutinas.
Cuando se comienza con Perl, lo mejor es pedirle ayuda al propio Perl para que nos diga que es lo que hemos escrito mal.
Para eso, lo mejor es escribir los programas con este encabezado:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
El 'strict' nos obligará a programar de forma 'estricta': todas las variables deberán ir declaradas con my(). Si no, Perl nos dirá que quizás nos hemos equivocado a la hora de escribir alguna variable.
El 'warnings' activará los sistemas de alertas, y Perl nos avisará de cualquier cosa rara que vea. El 'diagnostics' nos dará aún más información sobre esas advertencias.
Si coloco esas líneas en tu programa, salen un montón de errores, a causa sobre todo del modo 'strict'. Si desactivo esa línea, solo salen advertencias, siendo las dos primeras:
Using text Syntax Highlighting
Prototype after '@' for main::suma : my@a,my@b,my@c at code_34608.pl line 45 (#1)
(W illegalproto) A character follows % or @ in a prototype. This is
useless, since % and @ gobble the rest of the subroutine arguments.
Illegal character in prototype for main::suma : my@a,my@b,my@c at code_34608.pl
line 45 (#2)
(W illegalproto) An illegal character was found in a prototype declaration.
Legal characters in prototypes are $, @, %, *, ;, [, ], &, \, and +.
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
que quiere decir que has construido mal la definición de las funciones.
En lugar de
Using perl Syntax Highlighting
sub suma (my @a, my @b, my @c) {
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
se debe escribir así:
Using perl Syntax Highlighting
sub suma () {
my(@a, @b, @c)= @_; # los argumentos son pasados a través de la variables especial @_
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
y aquí tenemos otro problema...
Cuando hacemos una llamada con
array y
hash, Perl "despliega" todos los elementos de esas variables, y los manda como una única lista de elementos hacia la subrutina. Ejemplo: si tenemos esto:
my @a = qw( 0 0 0 0 );
my @b = qw( 0 1 1 0 );
suma(@a, @b);Perl hará la llamada así:
suma( 0, 0, 0, 0, 0, 1, 1, 0 ); Entonces, cuando llega a la línea, dentro de la subrutina:
my(@x, @y) = @_;Perl "mete" todos los valores en @x, y no deja ninguno para @y. Perl no sabe que eran dos
array separados. Una vez hecho el despliegue, no hay forma de saber cuántos elementos tiene cada uno (bueno, se podría saber, haciendo alguna trampa).
En el caso de querer pasar (más de un)
array o (más de un)
hash, lo normal es hacerlo por "referencia":
suma(\@a, \@b);En esa llamada estamos pasando exactamente dos valores escalares: dos referencias, una a cada uno de los
array. En la subrutina, solo queda recibirlos:
my($array1_ref, $array2_ref) = @_; # recibimos dos valores escalaresy ya podemos acceder a los elementos de cada uno de ellos, pero como son referencias, hay que hacerlo con una indirección:
print $array1_ref->[0]; # primer elemento del primer arrayo a todos:
for my $celda (@$array2_ref) { # recorremos todos los valores, directamentefor(my $j = 0; $j < @$array2_ref; $j++) { # recorremos todos los índices de los valores(La notación '_ref' es solo eso: una notación. Sirve para que, visualmente, sepamos que esas escalares almacenan una referencia, y que entonces deben ser accedidas de una forma especial).
Más información en tu propio ordenador en
perldoc perlsub,
y en la Web.
Aparte, hay más detalles... en la línea 25 estás llamando a suma() sin pasarle ningún argumento.
Si quieres trabajar con una matriz bidimensional, a veces es mejor usar una estructura bidimensional:
Using perl Syntax Highlighting
my @matriz = (
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 1, 1, 0 ],
[ 0, 1, 1, 0, 0, 0 ],
[ 0, 1, 1, 0, 1, 0 ],
[ 0, 1, 0, 1, 1, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
);
print "Elemento 3,2 = ", $matriz[2][1], "\n";
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Más información en tu propio ordenador en
perldoc perllol,
y en la Web (
traducido al español).
(*) Por medio de módulos sí que es posible usar firmado de subrutinas.