Subrutinas que devuelven valores

Ya que sabemos cómo declarar e invocar subrutinas, ahora veremos cómo podemos escribir subrutinas que devuelvan valores. Una vez más, creo que un ejemplo deja todo más claro:

#!/usr/bin/perl -w 
# Ejemplo escrito por Bruno Contreras 

use strict; 

## variables del programa principal
my $queryseq = "MARRKRRNFNKQATEILNEYFYSHLSNPYPSXXXXXXXXXXSGITVSQVSNWFGNKRIRYKKNIGKFQEEANIYAAKTAVTA";
my $subjectseq = "MARRKRRNFNKQATEILNEYFYSHLSNPYPSEEAKEELAKKSGITVSQVSNWFGNKRIRYKKNIGKFQEEANIYAAKTAVTA";

## llamada a printf que a su vez llama a dos subrutinas que devuelven valores
printf("Alineamiento %2.2f :\n%s\n%s\n%s\n", 
	calculaIdentidad($queryseq,$subjectseq),  # llamada a una subrutina
	decoraAlineamiento($queryseq,$subjectseq));  # llamada a otra subrutina

## no siempre imprimiremos los valores devueltos por una subrutina, a veces simplemente los
## guardaremos:

my ($dev1,$dev2,$dev3) = decoraAlineamiento($queryseq,$subjectseq);


######## declaraciones de subrutinas ######################################

sub calculaIdentidad     
{
	# parametros
	my ($sec1,$sec2) = @_;
	
	# variables locales
	my ($id,$pos,$long) = (0,0,length($sec1));
	
	for($pos=0;$pos<$long;$pos++)
	{
		if(substr($sec1,$pos,1) eq substr($sec2,$pos,1))
		{
			$id++;
		}
	}
	
	return sprintf("%2.2f",$id/$long);  # devuelve un real
}

###########################################################################

sub decoraAlineamiento
{
	my ($sec1,$sec2) = @_;
	
	# variables locales
	my ($decoracion,$pos,$long) = ("",0,length($sec1));
	
	for($pos=0;$pos<$long;$pos++)
	{
		if(substr($sec1,$pos,1) eq substr($sec2,$pos,1))
		{
			$decoracion .= '|';
		}
		else
		{
			$decoracion .= ' ';
		}
	}
	
	return ($sec1,$decoracion,$sec2); # devuelve tres cadenas de caracteres
}

Es común llamar funciones a las subrutinas que devuelven valores y procedimientos a las que no. Si una subrutina contiene la función return, entonces será una función.

A diferencia de otros lenguajes, en Perl una función puede devolver más de un valor, como habéis comprobado con decoraAlineamiento.

A diferencia de otros lenguajes, en Perl los procedimientos pueden invocarse de manera diferente a las funciones, usando &procedimiento; en vez de procedimiento();.

Bruno Contreras-Moreira
http://www.eead.csic.es/compbio