viernes, 3 de junio de 2011

Extensión de clases en Scala

En algunos lenguajes de programación dinámicos como ruby se permite añadir funcionalidad a clases ya existentes. Cuando esto ocurre, se dice que las clases en ese lenguaje son 'abiertas'.

Un lenguaje de programación con clases abiertas añade mucha flexibilidad para el programador, sin embargo, esta flexibilidad hace que sea más difícil auditar el código.

La principal ventaja de esta técnica es poder aumentar la funcionalidad de las clases que proporciona en lenguaje. Al tener unos tipos básicos con una interfaz más rica, el código comienza a ser más sencillo y se reduce el número de líneas de código para desarrollar una funcionalidad.

En Scala, las clases no son abiertas, sin embargo, tiene un mecanismo similar con el que se pueden llegar a resultados no muy distintos.

Ejemplo:

class RomanNumber(val number:Int){
def toRoman:String = {
if(number == 1) return "I";
else if(number == 2) return "II";
else if(number == 3) return "III";
else if(number == 4) return "IV";
else if(number == 5) return "V";
else return "Unknown";
}
}

object Main extends Application{
implicit def intRomanNumber(x:Int) = new RomanNumber(x);

override def main(args: Array[String]){
println(1.toRoman);
println(3.toRoman);
println(5.toRoman);
println(6.toRoman);
}
}

En este ejemplo se crea una clase 'RomanNumber' que contiene la funcionalidad que necesitamos añadir a los enteros 'toRoman'.

El código resultaría muy redundante si cada vez que queremos usar el método 'toRoman' necesitamos crear una instancia de la clase y pasarle como argumento el entero. Algo como: new RomanNumber(4).toRoman.

Para este tipo de casos, Scala provee del mecanismo de conversión implícita, en el ejemplo el método 'intRomanNumber'.
Al definir un método como 'implicit' se llamará para hacer el correspondiente cambio de tipos como se le indique, en este caso creando una instancia de 'RomanNumber'.

El resultado final es el que aparece en el ejemplo, parece que los métodos añadidos mediante conversión implícita pertenezcan a la clase original, muy similar al caso de los lenguajes dinámicos y las clases abiertas.