2011-03-09 15 views
5

Estoy buscando una documentación concisa de todos los ganchos en Scala. Un gancho es cualquier situación en el flujo del programa donde el comportamiento común puede ser interceptado. Tales situaciones incluyen:Patrón de gancho en Scala

  • declaración de clases o rasgos
  • acceso a los métodos y campos
  • confusión en los hilos, la herencia

estoy procedentes de un fondo de Ruby donde, por ejemplo, method_missing permite interceptar llamadas a métodos inexistentes.

¿Hay tales ganchos disponibles en Scala?

Matthias

+0

En una nota relacionada, vea también http://stackoverflow.com/questions/3105594/is-there-a-method-missing-in-scala – VonC

Respuesta

7

No hay un equivalente de method_missing en Scala 2.8 o anterior. En Scala 2.9 (en desarrollo), se agregará un rasgo Dinámico. Llamadas de métodos desconocidos a los objetos que declaran que el rasgo dinámico será traducido automáticamente por el compilador para llamar en su lugar al invokeDynamic. La idea es obtener algo del poder de los lenguajes de tipeo dinámico de una manera segura y sensata, sin pagar la sobrecarga de rendimiento de tipeo dinámico si no es necesario. También simplifica los problemas de interoperabilidad al llamar objetos definidos en lenguajes dinámicos desde dentro de Scala.

Aparte de eso, el enganche en el nuevo comportamiento en Scala se hace principalmente a través de la herencia clásica, o agregando nuevas funcionalidades a los objetos a través de conversiones implícitas.

3

No, no lo son. En lenguajes estáticos, la programación orientada a aspectos se puede usar para algunos de los mismos propósitos. Ver Can I do Aspect Oriented Programming in Scala? Pero, por supuesto, "declaración de clases o rasgos" y "mezcla de hilos, herencia" son no parte del flujo de control. Si quiere interceptarlos, necesitará un complemento de compilación.

3

Scala tiende a fomentar el uso de cierres en lugar del tipo de ganchos del que está hablando (la mayoría de los cuales no puede implementarse convenientemente debido a tipeo y compilación estáticos).

Esto requiere que sepa de antemano dónde puede desearse la flexibilidad en el comportamiento común, pero es muy potente y fácil de usar cuando está disponible. Por ejemplo, suponga que tiene un método que imprime nombres de las personas:

case class Name(first: String, last: String) { 
    def title = last + ", " + first(0).toUpper + "." 
} 
trait Familiar extends Name { 
    override def title = first + " " + last(0).toUpper + "." 
} 

def listing(names: Array[Name]) = names.foreach(name => println(name.title)) 

val jd1 = new Name("John","Doe) 
listing(Array(jd1)) // Prints Doe, J. 
val jd2 = new Name("John","Doe") with Familiar 
listing(Array(jd2)) // Prints John D. 

pero si lo que realmente va a estar cambiando de nombre imprimir una gran cantidad, usted es mejor que en la construcción:

case class Name(first: String, last: String) { 
    def title = last + ", " + first(0).toUpper + "." 
} 

def listing(names: Array[Name], address: Name => String = _.title) = 
    names.map(address).foreach(println) 

val jd = new Name("John", "Doe") 
listing(Array(jd)) // Uses default, so prints Doe, J. 
listing(Array(jd), n => n.first + " " + n.last(0).toUpper + ".") // Prints John D. 
1

No existe tal cosa en Scala.

O, para decirlo de forma más precisa, el tipado estático garantiza que sepamos qué sucederá en el momento en que se compila el código. Cualquier gancho de este tipo cambiaría el comportamiento en el tiempo de ejecución, lo que frustraría el propósito del tipado estático.

Se puede modificar el comportamiento en compilar tiempo, a través de complementos de compilador, o incluso cambiar cosas en el tiempo de carga de clase, a través de cargadores de clases.