Иногда я вижу методы в Ruby, которые имеют?? а также "!" в конце их, например:
name = "sample_string"
name.reverse
name.reverse!
name.is_binary_data?
Мне было интересно, какова их цель? Являются ли они просто синтаксическим покрытием из сахара?
Иногда я вижу методы в Ruby, которые имеют?? а также "!" в конце их, например:
name = "sample_string"
name.reverse
name.reverse!
name.is_binary_data?
Мне было интересно, какова их цель? Являются ли они просто синтаксическим покрытием из сахара?
Это "просто сахарное покрытие" для удобочитаемости, но они имеют общие значения:
!
, выполняют некоторые постоянные или потенциально опасные изменения; например:
Enumerable#sort
возвращает отсортированную версию объекта, а Enumerable#sort!
сортирует его на месте.ActiveRecord::Base#save
возвращает false, если сохранение завершилось неудачно, а ActiveRecord::Base#save!
вызывает исключение.Kernel::exit
вызывает выход script, а Kernel::exit!
делает это немедленно, минуя любые обработчики выходных данных.?
, возвращают логическое, что делает поток кода еще более интуитивно похожим на предложение - if number.zero?
читается как "если число равно нулю", но if number.zero
просто выглядит странно.В вашем примере name.reverse
оценивает обратную строку, но только после того, как строка name.reverse!
содержит переменную name
, на самом деле содержит обратное имя. name.is_binary_data?
выглядит как "есть name
двоичные данные?".
Вопросительный знак указывает, что метод возвращает логическое значение. Уже здесь ответил:
Что означает оператор-знак вопроса в Ruby?
Значок указывает, что метод действует на самом объекте. Уже здесь ответил:
В Ruby ?
означает, что метод возвращает логическое значение, а !
изменяет объект, на который он был вызван. Они предназначены для улучшения читаемости при просмотре кода.
В отличие от - я полагаю - большинство языков программирования...
Ruby, методам разрешается заканчивать вопросительными знаками или восклицательными знаками.
По соглашению методы, которые отвечают на вопросы (т.е. Array # empty? возвращает true, если приемник пуст) заканчиваются знаками вопроса.
Потенциально "опасные" методы (т.е. методы, которые изменяют себя или аргументы, выходят! и т.д.) по завершении соглашения с восклицательными знаками.
От: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/, раздел Смешные имена методов
Остерегайтесь, это не всегда так. Возьмем, к примеру, Ruby Array # concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat.
Если вы можете сильно сгореть, это что-то вроде MyActiveRecordModel.column_names.concat([url])
. Более поздние вызовы, связанные с MyActiveRecordModel, попытаются найти столбец "url" для MyActiveRecordModel и throw.
Вместо этого вы должны клонировать его перед выполнением concat. К счастью, мой набор тестов поймал этот, но... хедз-ап!