Крючок в Скала - PullRequest
       9

Крючок в Скала

5 голосов
/ 09 марта 2011

Я ищу краткую документацию по всем хукам в Scala.Хук - это любая ситуация в потоке программы, где обычное поведение может быть перехвачено.Такие ситуации включают:

  • объявление классов или признаков
  • доступ к методам и полям
  • смешивание потоков, наследование

Я пришел из Ruby, где, например, method_missing позволяет перехватывать несуществующие вызовы методов.

Есть ли такие ловушки в Scala вообще?

Matthias

Ответы [ 4 ]

7 голосов
/ 09 марта 2011

Нет эквивалента method_missing в Scala 2.8 или более ранней версии. В Scala 2.9 (в разработке) будет добавлена ​​динамическая черта. Вызовы неизвестных методов для объектов, объявляющих динамическую черту, будут автоматически переведены компилятором вместо вызова invokeDynamic. Идея состоит в том, чтобы получить некоторую мощь динамически типизированных языков безопасным и разумным способом, без дополнительных затрат на динамическую типизацию, если в этом нет необходимости. Это также упрощает вопросы взаимодействия при вызове объектов, определенных в динамических языках, из Scala.

Кроме этого, зацепление нового поведения в Scala в основном осуществляется либо посредством классического наследования, либо путем добавления новых функций к объектам посредством неявных преобразований.

3 голосов
/ 09 марта 2011

Scala склонен поощрять использование замыканий вместо того типа хуков, о котором вы говорите (большинство из которых он не может реализовать удобно из-за статической типизации и компиляции).

Для этого необходимо заранее знать, где может потребоваться гибкость в обычном поведении, но он очень мощный и простой в использовании, когда он доступен. Например, предположим, у вас есть метод, который печатает имена людей:

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.

но если вы действительно собираетесь много менять печать имен, вам лучше встроить это в:

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.
3 голосов
/ 09 марта 2011

Нет, это не так.В статических языках аспектно-ориентированное программирование может использоваться для одних и тех же целей.См. Могу ли я заниматься аспектно-ориентированным программированием в Scala? Но, конечно, "объявление классов или признаков" и "смешивание потоков, наследование" являются не частью потока управления,Если вы хотите перехватить их, вам понадобится плагин компилятора.

1 голос
/ 09 марта 2011

В Scala такого нет.

Или, если быть более точным, статическая типизация гарантирует, что мы знаем, что произойдет во время компиляции кода. Любой такой хук изменит поведение во время выполнения, что лишит цель статической типизации.

Можно изменить поведение при времени компиляции через плагины компилятора или даже изменить вещи во время загрузки класса через загрузчики классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...