Почему некоторые методы Ruby нуждаются в взрыве, а другие не являются разрушительным методом?
например, array.pop
не нужен взрыв, чтобы навсегда изменить массив. Почему это так и каковы были причины разработки этих определенных методов Ruby без этого соответствия?
4 ответов
методы взрыва чаще всего используются для различения опасной и безопасной версии одного и того же метода. Вот несколько примеров, которые можно было бы различить с помощью комбинации bang / no-bang:
- методы мутатора - одна версия изменяет объект, другая возвращает копию и оставляет исходный объект без изменений
- при возникновении ошибки одна версия выдает исключение, а другая только записывает сообщение об ошибке в журнал или ничего не делает
однако Конвенция оставлять челку, если есть только одна версия, которая имеет смысл. Например, pop
ing массив без фактического изменения его не имеет смысла. В этом случае это будет другая операция:Array#last
. Многие методы изменяют вызываемый объект, например сеттеры. Нам также не нужно писать их с треском, потому что ясно, что они меняют объект.
наконец, есть несколько исключения из этого, где некоторые разработчики могут использовать метод bang без реализации аналога без взрыва. В этих случаях взрыв просто используется как способ сделать вызовы метода выделиться визуально. Например:
- метод делает что-то опасное или деструктивное
- метод делает что-то неожиданное
- метод оказывает значительное влияние на производительность
взрыв используется для различения опасной и менее опасной версии того же метода. Есть только один pop
метод, поэтому различать нечего.
Примечание: название метода не имеет абсолютно никакого отношения к тому, что он делает. Является ли метод деструктивным или нет, зависит от того, какой код он выполняет, а не какое имя он имеет.
суффикс !
означает, что метод является опасной версией другого метода. Например, save!
является опасной версией save
. Опасно может означать редактирование на месте, делать что-то с более строгими ошибками и т. д. Не требуется использовать !
суффикс на методе, который опасен, но не нуждается в более безопасном аналоге. Кроме того, это просто соглашение об именах, поэтому Ruby не ограничивает то, что вы можете и не можете сделать, если метод завершается или не заканчивается !
.
существует распространенное заблуждение, что каждый метод, который редактирует что-то на месте, должен заканчиваться !
. Это неправда, !
требуется только тогда, когда существует более опасная версия метода, которая уже существует, и это не обязательно означает, что опасный метод редактируется на месте. Например, в Rails,ActiveRecord::Base#save!
версия ActiveRecord::Base#save
который выполняет проверки.
значение взрыва в Ruby - "осторожность". Это означает, что вы должны использовать метод с осторожностью, не более того. Я больше не могу найти ссылку, но люди власти прямо сказали, что bang destructive разрушительный метод. Bang - это просто семантический элемент, связанный с осторожностью. Программист должен взвесить все и решить, когда использовать bang.
например, в моем симуляторе gem я использую #step
метод для получения размера шага.
simulation.step #=> 0.42
и step!
метод фактического выполнения шага моделирования.
simulation.step! #=> takes the simulation to the next time step
а #reset
метод, я решил, что слово "сброс" достаточно многословно, и нет необходимости использовать bang, чтобы предупредить пользователя, что состояние моделирования будет уничтожено:
simulation.reset #=> resets the simulation back to the initial state