Использование ›› в Pharo/Smalltalk

Я реализую фьючерсы в Pharo. Я наткнулся на этот сайт http://onsmalltalk.com/smalltalk-concurrency-playing-with-futures. Я следую этому примеру и пытаюсь воспроизвести его на Pharo. Однако я дошел до этого последнего шага и понятия не имею, что означает «>>»: этот символ также не включен как часть синтаксиса Smalltalk в http://rigaux.org/language-study./syntax-across-languages-per-language/Smalltalk.html.

BlockClosure>>future
    ^ SFuture new value: self fixTemps

Я вижу, что будущее не является переменной или методом, реализованным BlockClosure. Что мне делать с этой частью кода, чтобы промисы/фьючерсы работали, как указано в http://onsmalltalk.com/smalltalk-concurrency-playing-with-futures? Я не могу добавить его на Playground или в качестве метода в свой класс Promise, или я что-то упустил?

После добавления будущего метода в BlockClosure я пробую этот код на PlayGround.

value1 := [200 timesRepeat:[Transcript show: '.']. 6] future.
value2 := [200 timesRepeat:[Transcript show: '+']. 6] future.
Transcript show: 'other work'.
Transcript show: (value1 + value2).
Date today 

Стенограмма отображает приведенную ниже ошибку вместо ожидаемого значения 12.

UndefinedObject>>DoIt (value1 is Undeclared) 

UndefinedObject>>DoIt (value2 is Undeclared) 

person Gakuo    schedule 21.04.2018    source источник


Ответы (1)


По какой-то причине, которую было бы неплохо узнать, в Smalltalk существует традиционная нотация для ссылки на метод с селектором, скажем, m в классе C, который равен C>>m. Например, BlockClosure>>future обозначает метод BlockClosure с селектором #future. Интересно, что это выражение не является выражением Smalltalk, поддающимся оценке, то есть оно не является выражением Smalltalk. Это просто краткий способ сказать: «ниже приведен исходный код метода m в классе C». Только то.

Однако в Smalltalk методы тоже являются объектами. На самом деле они являются экземплярами CompiledMethod. Это означает, что их можно получить, отправив сообщение. В данном случае это сообщение methodAt:. Получателем сообщения является класс, который реализует метод, а аргументом является селектор (соответственно, C и #m или BlockClosure и #future в вашем примере).

Поэтому в большинстве диалектов используется синоним methodAt: с именем >>. Это легко сделать таким образом:

>> aSymbol
  ^self methodAt: aSymbol

Это приближает синтаксис Smalltalk к традиционной нотации, потому что теперь BlockClosure>>future выглядит как выражение, которое отправляет сообщение >> в BlockClosure с аргументом future. Однако future не является Symbol, если только мы не добавим к нему #, а именно #future. Таким образом, если мы поставим перед селектором знак #, мы получим буквальное значение Symbol #future, которое является допустимым объектом Smalltalk. Теперь выражение

BlockClosure >> #future

становится сообщением, а его результат после его оценки — CompiledMethod с селектором #future в классе BlockClosure.

В общем, BlockClosure>>future — это нотация, а не допустимое выражение Smalltalk. Однако, изменив его на BlockClosure >> #future, он становится вычисляемым выражением языка, возвращающим метод, на который ссылается нотация.

person Leandro Caniglia    schedule 22.04.2018
comment
Я добавил будущий метод в BlockClosure. Однако кажется, что ^SFuture new value: self fixTemps не работает, так как сообщение fixTemps отправляется, но не реализуется. Я просмотрел этот веб-сайт gnu.org/software/smalltalk/manual. -base/gst-base.html. Вот что он говорит о fixTemps: fixTemps: - Это должно исправить значения временных переменных, используемых в блоке, которые обычно используются совместно с методом, в котором определен блок. Еще не определено, но это не вредно, что это не так. Ответьте получателю. В нем указано, что еще не определено. Как я могу решить эту проблему? - person Gakuo; 22.04.2018
comment
@Gakuo Вам не нужно fixTemps в Pharo. Просто отправьте self в качестве аргумента. - person Leandro Caniglia; 22.04.2018
comment
Покончив с fixTemps, я попытался запустить тестовый код, указанный на веб-сайте. Я получаю сообщение об ошибке: UndefinedObject››DoIt (значение1 не объявлено) и UndefinedObject››DoIt (значение2 не объявлено). Я ожидал, что этот код будет работать так, как указано на веб-сайте onsmalltalk.com/smalltalk-concurrency-playing. -с-фьючерсами - person Gakuo; 22.04.2018
comment
@Gakuo Переменные value1 и value2 определены как экземпляры SFuture, поэтому, если вы оцените эти выражения, эти переменные будут объявлены. Тот факт, что вы получаете их как необъявленные, означает, что вы не оценили эти назначения. По крайней мере, это единственное, что я могу представить, не видя того, что вы делаете. - person Leandro Caniglia; 22.04.2018
comment
Я считаю, что это должна быть какая-то другая причина. Я выполняю каждую строку за раз (ctrl -D ), а также пытаюсь выполнить весь тест сразу. Отладчик всплывает, и стенограмма отображает UndefinedObject››DoIt (значение1 не объявлено) и UndefinedObject››DoIt (значение2 не объявлено) для обоих случаев. - person Gakuo; 22.04.2018
comment
@Gakuo Попробуйте игровую площадку вместо стенограммы. - person Leandro Caniglia; 22.04.2018
comment
Давайте продолжим обсуждение в чате. - person Gakuo; 23.04.2018
comment
Ваша помощь была высоко оценена. У меня есть дополнительные вопросы по адресу: stackoverflow.com/questions/50071106/ - person Gakuo; 28.04.2018