Можно ли пропустить [и] для сообщений вроде at:ifAbsent: если вам не нужен полный блок?
В Smalltalk (и особенно в Pharo/Squeak) я хочу знать, можно ли пропустить "[" и "]" для аргумента сообщений, таких как at:ifAbsent: если вам не нужен блок, например так;
^ bookTitles at: bookID ifAbsent: ''.
а также
^ books at: bookID ifAbsent: nil.
код работает, потому что (в Pharo/Squeak) Object>>value просто возвращает self. Но я хочу знать, насколько приемлемо это использование или нужно ли вам всегда вводить [и], даже если вам все равно, будет ли аргумент вычисляться быстро или более одного раза.
5 ответов
Подпись:
at: key ifAbsent: aBlock
объявляет о намерении использовать блок в качестве второго параметра... Но Smalltalk не является строго типизированным языком, так что за объекты вы можете передавать туда? любой вид, который понимает сообщение #value, поэтому будьте осторожны с каждым конкретным значением #value в каждом случае, но пользуйтесь преимуществами полиморфизма!
Вот что критики кода Pharo говорят о подобных ситуациях:
Неблоки в специальных сообщениях:
Проверяет методы, которые не используют блоки в специальных сообщениях. Люди, плохо знакомые с Smalltalk, могут написать код, такой как: "aBoolean ifTrue: (self doSomething)" вместо правильной версии: "aBoolean ifTrue: [self doSomething]". Даже если эти части кода могут быть правильными, они не могут быть оптимизированы компилятором.
Это правило можно найти в Оптимизации, так что вы, вероятно, можете его игнорировать, но я думаю, что в любом случае лучше использовать блок.
Обновить:
at:ifAbsent:
не запускается этим правилом. И это не оптимизировано компилятором. Поэтому оптимизация не является основанием для использования блоков в этом случае.
Не все диалекты Smalltalk реализуют #value на объекте из коробки, поэтому ваш код может не работать на других диалектах Smalltalk, если вы передаете объект, который не понимает #value.
Можно передавать объекты любого типа, если вы знаете, что то, что делает #value, это то, что вы ожидаете,
Ваш код может показаться странным для людей, которые приходят с других диалектов smalltalk или являются новичками в Smalltallk, потому что они узнали, что вы передаете здесь блок, но отправляет сообщения типа #join: в коллекцию строк...
В конце я бы сказал, не волнуйтесь, если переносимость не является для вас серьезной проблемой.
Я бы сказал, что не стоит оставлять их без внимания. Аргумент будет оценен с нетерпением, если вы пропустите парены, и вам будет отправлено #value. Так что, если у "slef doSomething" есть побочные эффекты, это было бы плохо. Также может быть плохо, если #value делает что-то, чего вы не ожидаете, например, возможно, надуманный
bookTitles at: bookID ifAbsent: 'Отсутствует заголовок' -> 'ISBN-000000'
Если ваш код работает, и вы единственный, кто просматривает исходный код, тогда все в порядке. Если бы другие видели источник, я бы сказал, что пустой блок [] был бы более читабельным. Но, вообще говоря, если вы действительно заботитесь об ошибках, не стоит выходить за рамки стандартной практики, потому что нет способа гарантировать, что у вас не возникнет никаких проблем.