Un módulo provee un mecanismo para agrupar variables y funciones en mat|r script. Al ejecutar una aplicación, los módulos generan un alcance global (scope), donde sus variables son almacenadas. Este alcance se mantiene vivo durante todo el ciclo de vida de la aplicación.Una función en mat|r script mat|r es un bloque de código autónomo que permite ejecutar sentencias de código. Cuando se ejecuta una función el control pasa al punto donde esta inicia. Una vez finalizada su ejecución, se devuelve el control al punto desde el que se hizo la llamada a la función. No se permite sobrecarga de funciones, es decir mismo nombre de funciones con distintos parámetros.

Contenido

Módulos

La sintaxis que permite definir un módulo es la palabra reservada Module, como se muestra en el siguiente código de ejemplo:

Module Salario {
  Double  porcentVacaciones
  Integer salarioBase
}

Variables de Módulo

Las variables pueden ser tipos simples como: Integer,Double, String, Date, Bool, o a su vez de tipos compuestos: Model, Array, Map.
Las variables pueden ser accedidas y asignadas de forma estática: Salario.salarioBase. Es decir que para acceder a una variable de un módulo, se especifica el nombre del módulo seguido por un punto y el nombre de la variable.

Ejemplos de definición de variables de diferentes tipos:

Module Salario {
  Double               porcentVacaciones
  Integer              salarioBase
  Bool                 esContratoMensual
  Array<Integer>       mesesContrato
  Map<Persona>         empleados
}

Acceso a variables:

Double salario = Salario.salarioBase + 10 * Salario.porcentVacaciones

Asignación de valor a una variable de módulo:

Salario.salarioBase = 12000

Funciones

Una función es definida dentro de un módulo. Las funciones pueden tener 0, 1 o más parámetros y la misma puede o no tener un valor de retorno. La sobrecarga de funciones no está permitida, por lo que en un módulo no pueden existir dos funciones con el mismo nombre.

Parámetros de Función

Los parámetros de función son un conjunto de argumentos, separados por comas y encerrados entre paréntesis. Para cada parámetro, se debe definir su tipo (simple o compuesto) y un nombre. Los parámetros en una función se pasan por referencia.

A continuación se ejemplifica la definición de parámetros para una función:

funcionSalarioBase(Integer aniosConsolidados){
    ...
}

funcionSalarioEmpleados(Integer aniosConsolidados, Array<Persona> empleados){
    ...
}

Funciones con retorno

Mat|r permite definir una función con retorno especificando: el tipo de retorno, nombre de función, paréntesis con sus parámetros y el cuerpo de la función que se define con llaves, donde se declaran las variables locales y se escriben las instrucciones a ejecutar. El cuerpo de la función termina con la sentencia return que marca el final de la función.

Así declaramos una función con retorno:

Persona getPersonaPorNombre(String nombre) {
    return broker.localPersistence.get(nombre)
}

Se debe aclarar que la sentencia return también se emplea para cortar la ejecución, con lo cual si se definen instrucciones por debajo de un return no serán ejecutadas.

Funciones sin retorno

Para las funciones sin retorno se debe especificar la sentencia void previo a la definición del nombre de función. No se emplea la sentencia return, salvo que se considere necesario para cortar con la ejecución las instrucciones que posee.

Así declaramos una función sin retorno:

void procesarPagosSalarios(Array<Persona> empleados) {
    service.procesarPagos.call(empleados)
}

Acceso a variables dentro de una función.

Dentro del bloque de una función se pueden acceder a las variables locales, a las definidas en el módulo que contiene a la función y a las globales.


Module Salario {
  Double                 porcentVacaciones
  Integer                salarioBase
  Bool                   esContratoMensual
  Array<Integer>   mesesContrato
  Map<Persona>     empleados

  Double obtenerSalarioBase(Integer aniosConsolidados) { 
    return (Salario.salarioBase + (aniosConsolidados * Salario.porcentVacaciones)) 
  } 
}

Además, para acceder a las variables del módulo dentro del cuerpo de una función, puede omitirse el prefijado del nombre del módulo, por ejemplo:


Module Salario {
  Double                 porcentVacaciones
  Integer                salarioBase
  Bool                   esContratoMensual
  Array<Integer>   mesesContrato
  Map<Persona>     empleados

  void aumentarSalarioBase(Double porcentajeAumento) {
     salarioBase = salarioBase*(1 + porcentajeAumento)
  }
} 

Llamada a funciones

Las funciones pueden ser invocadas de manera estática desde cualquier bloque de ejecución:

nombreModulo.nombreFuncion([parametros])

A continuación mostramos la definición de un módulo con dos funciones y la forma en que se invocan desde una regla:


Module Salario {
	Double   porcentVacaciones
	Integer  salarioBase

	Double obtenerSalarioBase(Integer aniosConsolidados) {
		return (Salario.salarioBase + (aniosConsolidados * Salario.porcentVacaciones))
	}

	void procesarPagosSalarios(Array<Persona> empleados) {
		service.procesarPagos.call(empleados)
	}
}

RuleContext ReglasDeSalario {
	Rule procesarSalariosBase {
		// asignacion valor variables
		Salario.salarioBase = 12000
		Salario.porcentVacaciones = 0.25
		Array<String> empleados = services.getEmpleados()
		//invocación de funciones
		Double salarioBase = Salario.obtenerSalarioBase(15)
		Salario.procesarPagosSalarios(empleados)
	}
}