Предположим, что у меня есть объект, x
, который может принимать любой из селекторов, s1
, s2
, ..., sn
. Предположим далее, что результатом любого из этих селекторов, работающих на объекте, является обновленный объект того же типа. Я мог бы тогда «цепь» эти селекторы (до тех пор, как они унарные сообщения), как я хочу, такие как:Цепочные сообщения ключевых слов
x s1 s2 ... sn
Это займет результат x s1
и применить селектор s2
, а затем применить селектор s3
к этот результат и т. д. Я хотел бы применить один или более из этих селекторов в определенном порядке для различных результатов:
x s8 s2
В Smalltalk я могу это сделать, если селекторы унарными сообщений. Однако, если мои селекторы - это сообщения с ключевыми словами, я больше не могу этого делать. Если x
индивидуально принимает селекторы, s1:
, s2:
, ..., sn:
, то следующее не работает:
x s1: a1 s2: a2 ... sn: an
Существует ;
оператор:
x s1: a1 ; s2: a2 ; ... ; sn: an
Но используя каскадные : каждый этап изменяет оригинал x
по пути, и в этом случае я не хочу изменять x
.
Для сообщений по ключевым словам цепи, я думаю, что я оставил, используя следующий синтаксис с помощью скобок:
(...(((x s1: a1) s2: a2) ... sn: an)
Что заставляет меня чувствовать, что я программирование в LISP, если у меня есть 3 или более keywrod сообщений. Конкретным примером этого может быть многомерный массив. Если foo
является 3 одномерный массив, и вы хотите получить доступ к объекту в месте 2,3,5 в массиве, я думаю, что это будет выглядеть так:
(((foo at: 2) at: 3) at: 5) some_object_selectors
Это тривиальный пример, конечно, но иллюстрирует случай. У вас могут быть другие типы встроенных объектов или другая цепочка последовательных операций с объектами, в которых вас интересует конечный результат.
Есть ли более синтаксически привлекательный способ сделать это в Smalltalk? Я предположив нет другого оператора, возможно, кузен к оператору ;
(скажем, мы используем &
, например), который бы приковать их, такие как:
x s1: a1 & s2: a2 & ... & sn: an
Так как я хотел бы применить селекторы в любом или почти любом желаемом порядке (для, возможно, разных результатов), селекторная форма, s1:s2:s3:...
слишком ограничена. Кроме того, это дает объект, который уже существует в других языках, таких как Ruby, где было бы то же самое выражается как:
x.s1(a1).s2(a2)...sn(an)
Не имея специального оператора, альтернативой может быть, чтобы передать массив пар селектора аргументов , или, возможно, таблицу поиска пар пар селектора.Таблица поиска требует установки для прохождения литералов (он должен быть создан и заполнен), что заставляет меня склоняться к массиву, так как я могу просто написать:
x { {s1. a1}. {s2. a2}. ... {sn. an} }
Это еще немного неуклюжим, и я m не настолько уверен, что это более элегантно, чем просто использовать все круглые скобки. Я боюсь, что мой вопрос может быть, по крайней мере, частично субъективным, но мне интересно узнать, что может быть лучшей практикой, и существует ли оператор, о котором я не знаю, что может помочь, или же кто-то развлекается Smalltalk нормативный орган.
Хороший вопрос, также иногда выражаемый как трубка сообщения или конвейер - ваш не первый, кто пропустил такую функцию, он регулярно обсуждается в списке рассылки. Я рекомендую отличный блог http://blog.3plus4.org/2007/08/30/message-chains/ –
@ aka.nice Да, похоже, они избили меня до 8 лет назад. :) – lurker