Вы ищете doesNotUnderstand:
. Если reduce
является объектом, который не реализует +
, но вы все равно отправляете его, то вместо этого будет вызываться его метод doesNotUnderstand:
. Обычно это просто вызывает ошибку. Но вы можете переопределить значение по умолчанию, получить доступ к селектору +
и другому аргументу и делать с ними все что угодно.
Для простоты создайте класс Reduce
. На стороне класса определите метод:
doesNotUnderstand: aMessage
^aMessage argument reduce: aMessage selector
Тогда вы можете использовать это так:
Reduce + (#(1 2 3) * #(4 5 6))
который в рабочем пространстве Squeak отвечает 32, как и ожидалось.
Это работает, потому что *
уже реализован для коллекций с подходящей семантикой.
Либо добавьте класс ApplyToAll
с помощью этого метода на стороне класса:
doesNotUnderstand: aMessage
^aMessage argument collect: [:e | e reduce: aMessage selector]
, а также добавьте этот метод к SequenceableCollection
:
transposed
^self first withIndexCollect: [:c :i | self collect: [:r | r at: i]]
Тогда вы можете написать
Reduce + (ApplyToAll * #((1 2 3) #(4 5 6)) transposed)
, что довольно близко к вашей первоначальной идее.