Subtrutinas

Las subrutinas se definen con la palabra clave sub e invocadas simplemente nombrándolas. Si la subrutina en cuestión no ha sido todavía declarada, es necesario, para el proceso de parseo, poner los paréntesis.
foo();           # paréntesis necesarios aquí...
sub foo { ... }
foo;             # ... pero no aquí
Una lista de argumentos pueden ser indicados después del nombre de la subrutina. Los argumentos pueden ser escalares, listas o hashes.
foo $x, @y, %z;
Los parámetros de una subrutina no necesitan ser declarados, ni en número ni en tipo; de hecho, pueden variar en cada llamada. Los arrays son expandidos a sus elementos, los hashes a una lista de pares clave/valor y todo el conjunto es pasado a la subrutina como una indiferenciada lista de escalares.
Cualesquiera de los argumentos pasados están disponibles para la subrutina en el array especial @_. Los elementos de @_ son asociados a los argumentos actuales; cambiando un elemento de @_ cambia el argumento correspondiente.
Los elementos de @_ pueden ser accedidos con los subíndices de la forma normal.
$_[0], $_[1]
Sin embargo, el código resultante puede ser difícil de leer y los parámetros tener una semántica de pase por referencia, que puede resultar algo no deseable.
Un modismo común es asignar @_ a una lista de variables con nombres.
my($x, $y, $z) = @_;
Esto afecta tanto a la mnemónica de los nombres de los parámetros como a la semántica de los valores pasados por valor. La palabra clave my indica que las siguientes variables están léxicamente embebidas en el bloque que las contienen.
Otro modismo es sacar los parámetros de @_. Esto es muy común cuando la subrutina toma un sólo argumento.
my $x = shift;  # Si no se dice nada, nos referimos a @_
Las subrutinas pueden devolver valores.
return 42, $x, @y, %z;
Si la subrutina no sale vía declaración return, entonces devuelve la última expresión evaluada en el cuerpo de la subrutina. Arrays y hashes en el valor de retorno son expandidos a una lista de escalares, igual que si fueran argumentos de una función.
La expresión devuelta es evaluada en el contexto de la llamada de la subrutina; esto puede sorprender al desprevenido.
sub lista {      (4, 5, 6)     }
sub array { @x = (4, 5, 6); @x }
 
$x = lista;  # devuelve 6 - último elemento de la lista
$x = array;  # devuelve 3 - número de elementos de la lista
@x = lista;  # devuelve (4, 5, 6)
@x = array;  # devuelve (4, 5, 6)
Una subrutina puede descubrir su contexto de llamada con la función wantarray.
sub cualquiera { wantarray ? (1, 2) : "Naranjas" }
 
$x = cualquiera;    # devuelve "Naranjas"
@x = cualquiera;    # devuelve (1, 2)