Отправка сообщений в функции в Scala - PullRequest
5 голосов
/ 19 июля 2011

Я пробираюсь через Семи языков Брюса Тейта за семь недель и с трудом понимаю его реализацию sizer.scala (Scala: День 3) В частности, рассмотрим следующий объект Singleton

object PageLoader {
    def getPageSize(url : String) = Source.fromURL(url).mkString.length
}

и следующий метод, который с помощью акторов вычисляет количество символов на каждой веб-странице, заданное массивом urls.

def getPageSizeConcurrently() = {
    val caller = self

    for(url <- urls) {
        actor { caller ! (url, PageLoader.getPageSize(url)) }
    }

    for(i <- 1 to urls.size) {
        receive {
            case (url, size) =>
                println("Size for " + url + ": " + size)
        }
    }
}
  1. Что означает self ? getPageSizeConcurrently? Возможно ли для self обращение к функции?
  2. Предполагая, что self относится к к getPageSizeConcurrently, считается ли это довольно стандартным в мире Scala? Зачем отправлять сообщения функции вместо объекта или наоборот?

ОБНОВЛЕНИЕ: В рассматриваемом коде self используется только один раз, но он начинается со следующих import операторов.

import scala.io._
import scala.actors._
import Actor._

При просмотре API Scala выясняется, что одноэлементный объект Actor имеет self метод . Даже если это self, назначенное caller, я не понимаю, почему будет выполняться блок receive.

Ответы [ 3 ]

4 голосов
/ 19 июля 2011

Существует метод self для объекта-компаньона Actor. Из scaladoc :

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

Я предполагаю, что ваш код импортировал объект Actor и что это метод self объекта Actor, который вызывает ваш код. Таким образом, вы получаете ссылку на основной поток актеров, в котором вы находитесь, и анонимные актеры, которым вы начинаете получать размер страницы, могут отправить сообщение обратно в поток, в котором вы находитесь.

2 голосов
/ 19 июля 2011

self не является ключевым словом Scala.

Хотя у меня нет этой книги, классы Scala допускают псевдонимы для себя;self обычно выбирают.Вот почему вы можете захотеть сделать это (не считая того, что вы можете ограничить тип, которым может быть класс при указании псевдонима):

class A {
  self =>
  val a = 7
  class B {
    val a = 7             // Uh-oh, we've shadowed the parent class a.
    val outerA = self.a   // Whew, we haven't lost it!
  }
}

Итак, self почти наверняка является классом, который реализуетметод getPageSizeConcurrently.

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

(Кстати, обратите внимание, что формально можно определить субъект, который расширяет черту Function. Таким образом, вы могли бы, на самом деле, отправить сообщениедля функции (объект функции, а не метод). Но синтаксис не будет выглядеть так, как у вас выше.)

1 голос
/ 19 июля 2011

Хотя актеры не связаны с потоками, как это было в более ранних версиях Scala, self сравним с Thread.current. Вы используете его, потому что Thread.current не имеет необходимых методов для просмотра текущего потока как актера.

"Какой класс или объект имеет getPageSizeConcurrently в качестве одного из своих методов?" - Rex Kerr

"Ничего, насколько я могу судить ..." - Крис

Я полагаю, self пытается обработать текущий поток как актер.

Примечание. Будьте осторожны при использовании self в REPL.

...