Почему некоторые методы Ruby нуждаются в взрыве, а другие не являются разрушительным методом?

например, array.pop не нужен взрыв, чтобы навсегда изменить массив. Почему это так и каковы были причины разработки этих определенных методов Ruby без этого соответствия?

4 ответов


методы взрыва чаще всего используются для различения опасной и безопасной версии одного и того же метода. Вот несколько примеров, которые можно было бы различить с помощью комбинации bang / no-bang:

  • методы мутатора - одна версия изменяет объект, другая возвращает копию и оставляет исходный объект без изменений
  • при возникновении ошибки одна версия выдает исключение, а другая только записывает сообщение об ошибке в журнал или ничего не делает

однако Конвенция оставлять челку, если есть только одна версия, которая имеет смысл. Например, poping массив без фактического изменения его не имеет смысла. В этом случае это будет другая операция: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