Почему восклицательные знаки используются в методах Ruby?

StackOverflow https://stackoverflow.com/questions/612189

Вопрос

В Ruby некоторые методы имеют знак вопроса (?) которые задают такой вопрос , как include? который спрашивает, включен ли рассматриваемый объект, затем возвращает значение true / false.

Но почему некоторые методы имеют восклицательные знаки (!) там, где другие этого не делают?

Что это значит?

Это было полезно?

Решение

Как правило, методы, заканчивающиеся на ! , указывают, что метод изменит объект, к которому он обращен . Ruby называет их как опасные методы " потому что они меняют состояние, на которое может ссылаться кто-то другой. Вот простой пример для строк:

foo = "A STRING"  # a string called foo
foo.downcase!     # modifies foo itself
puts foo          # prints modified foo

Это выведет:

a string

В стандартных библиотеках есть много мест, где вы увидите пары методов с одинаковыми именами, один с ! , а другой без. Те, у кого нет, называются «безопасными методами» и возвращают копию оригинала с изменениями, примененными к копии , при этом вызываемый абонент не изменяется. Вот тот же пример без ! :

foo = "A STRING"    # a string called foo
bar = foo.downcase  # doesn't modify foo; returns a modified string
puts foo            # prints unchanged foo
puts bar            # prints newly created bar

Это выводит:

A STRING
a string

Имейте в виду, что это просто соглашение, но многие классы Ruby следуют ему. Это также поможет вам отслеживать, что изменяется в вашем коде.

Другие советы

Восклицательный знак означает много вещей, и иногда вы не можете многое сказать из него, кроме "это опасно, будьте осторожны".

Как уже говорили другие, в стандартных методах он часто используется для обозначения метода, который заставляет объект мутировать сам, но не всегда. Обратите внимание, что многие стандартные методы меняют свой получатель и не имеют восклицательного знака ( pop , shift , clear ), а некоторые методы с восклицательным знаком точки не меняют своего получателя ( exit! ). См., Например, эту статью . / р>

Другие библиотеки могут использовать его по-другому. В Rails восклицательный знак часто означает, что метод генерирует исключение при сбое, а не при молчании.

Это соглашение об именах, но многие люди используют его немного по-разному. В вашем собственном коде хорошее правило состоит в том, чтобы использовать его всякий раз, когда метод делает что-то «опасное», особенно когда существуют два метода с одинаковым именем, и один из них более «опасен». чем другой. & Quot; Опасный & Quot; может означать почти все, что угодно.

Это соглашение об именах отменено из схемы .

  

1.3.5 Соглашения об именах

     

По соглашению, названия процедур   которые всегда возвращают логическое значение   обычно заканчиваются на ``? ''. Такие процедуры   называются предикатами.

     

По соглашению, названия процедур   которые хранят значения в ранее   выделенные места (см. раздел 3.4)   обычно заканчиваются на ``! ''. Такие процедуры   называются процедуры мутации. От   соглашение, значение, возвращаемое   процедура мутации не определена.

!обычно означает, что метод воздействует на объект вместо того, чтобы возвращать результат.Из книги Программирование на Ruby:

Методы, которые являются "опасными" или изменяют получателя, могут быть названы с завершающим знаком "!".

От themomorohoax.com:

Взрыв может использоваться следующими способами, в порядке моих личных предпочтений.

  

1) Метод активной записи вызывает ошибку, если метод не делает   что он говорит, что будет.

     

2) Метод активной записи сохраняет запись или метод сохраняет   объект (например, полоса!)

     

3) Метод что-то делает & # 8220; дополнительно & # 8221 ;, например, отправляет сообщения в другое место или делает   какое-то действие.

Суть в том, что используйте удар только тогда, когда вы действительно подумали, необходимо, чтобы избавить других разработчиков от необходимости проверьте, почему вы используете взрыв.

Взрыв предоставляет две подсказки другим разработчикам.

  

1) что нет необходимости сохранять объект после вызова   Метод.      

2) когда вы вызываете метод, БД будет изменена.

http: // www .themomorohoax.com / 2009/02/11 /, когда в использовании-а-бах-восклицательный-точка-после-рельсы-методы

Наиболее точно сказать, что методы с ударом! более опасный или удивительная версия. Есть много методов, которые мутируют без взрыва, например < code> .destroy , и в общем случае методы имеют челки только там, где в базовой библиотеке существует более безопасная альтернатива.

Например, в массиве у нас есть .compact и .compact! , оба метода изменяют массив, но .compact! возвращает nil вместо self, если в массиве нет nil, что более удивительно, чем просто возвращение self.

Единственный не мутирующий метод, который я нашел с треском, - это Kernel 's .exit! , что более удивительно, чем .exit , потому что вы не можете поймать < code> SystemExit во время закрытия процесса.

Rails и ActiveRecord продолжают эту тенденцию, поскольку используют взрыв для более «удивительных» эффектов, таких как .create! , что вызывает ошибки при неудаче.

Простое объяснение:

foo = "BEST DAY EVER" #assign a string to variable foo.

=> foo.downcase #call method downcase, this is without any exclamation.

"best day ever"  #returns the result in downcase, but no change in value of foo.

=> foo #call the variable foo now.

"BEST DAY EVER" #variable is unchanged.

=> foo.downcase! #call destructive version.

=> foo #call the variable foo now.

"best day ever" #variable has been mutated in place.

Но если бы вы когда-либо вызывали метод downcase! в приведенном выше объяснении, foo изменится на downcase навсегда. downcase! не возвращает новый строковый объект, но заменяет строку на месте, полностью изменяя foo на downcase. Я предлагаю вам не использовать downcase! , если это не является абсолютно необходимым.

!

Мне нравится думать об этом как о взрывном изменении, которое разрушает все, что было до него. Взрыв или восклицательный знак означает, что вы вносите постоянное сохраненное изменение в свой код.

Если вы используете, например, метод Ruby для глобальной замены gsub! , то сделанная вами замена является постоянной.

Другой способ представить это - открыть текстовый файл и выполнить поиск и замену с последующим сохранением. ! делает то же самое в вашем коде.

Еще одно полезное напоминание, если вы пришли из мира bash: sed -i имеет аналогичный эффект внесения постоянных сохраненных изменений.

Называется "Деструктивные методы" Они имеют тенденцию изменять оригинальную копию объекта, на который вы ссылаетесь.

numbers=[1,0,10,5,8]
numbers.collect{|n| puts n*2} # would multiply each number by two
numbers #returns the same original copy
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array
numbers   # returns [nil,nil,nil,nil,nil]

Итог: ! методы просто изменяют значение объекта, к которому они вызываются, тогда как метод без ! возвращает измененное значение без записи поверх объекта, к которому был вызван метод.

Используйте только ! если вы не планируете использовать исходное значение, сохраненное в переменной, для которой вы вызвали метод.

Я предпочитаю делать что-то вроде:

foo = "word"
bar = foo.capitalize
puts bar

или

foo = "word"
puts foo.capitalize

Вместо того, чтобы

foo = "word"
foo.capitalize!
puts foo

На всякий случай я хотел бы снова получить доступ к исходному значению.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top