Можно ли пропустить [и] для сообщений вроде 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'

Если ваш код работает, и вы единственный, кто просматривает исходный код, тогда все в порядке. Если бы другие видели источник, я бы сказал, что пустой блок [] был бы более читабельным. Но, вообще говоря, если вы действительно заботитесь об ошибках, не стоит выходить за рамки стандартной практики, потому что нет способа гарантировать, что у вас не возникнет никаких проблем.

Другие вопросы по тегам