В вашем коде нет цикла. В Ruby есть два вида циклов: while
и for
/ in
. (На самом деле, последний является просто синтаксическим сахаром для each
.)
В Ruby выражение оценивается как значение последнего подвыражения, вычисленного внутри выражения. Отправка сообщения оценивается как возвращаемое значение метода, который был выполнен в результате отправки сообщения. Возвращаемое значение метода - это либо явно значение выражения return
, которое завершило выполнение метода, либо неявно значение последнего выражения, вычисленного внутри тела метода. (Обратите внимание, что последнее выражение, вычисленное внутри тела, также является тем, что оценивает выражение определения модуля или класса. Однако выражение определения метода оценивается как Symbol
, обозначающее имя метода.)
Итак, что возвращает get_non_red_cats
? Ну, в нем нет return
, поэтому он возвращает значение последнего выражения, вычисленного внутри тела метода. Последнее выражение, вычисленное внутри тела метода, представляет собой отправку сообщения each
объекту, на который ссылается параметр привязки cats
. Следовательно, возвращаемое значение get_non_red_cats
- это возвращаемое значение метода, который выполняется в результате отправки сообщения each
на cats
.
И это все, что мы положительно знаем .
Мы можем сделать некоторые предположения , хотя. Как правило, each
должно возвращать self
. Это то, что делают все реализации each
во всей базовой и стандартной библиотеках, и это часть стандартного протокола Iterable в Ruby. Было бы очень необычно и очень запутанно, если бы это было не так. Таким образом, мы можем предположить , что независимо от того, что реализация each
завершится выполнением, она вернет self
, то есть получателя отправленного сообщения, т.е. объект, на который ссылается параметр привязки cats
.
Другими словами: метод get_non_red_cats
просто возвращает то, что было передано в качестве аргумента. Это довольно скучный метод. На самом деле, это метод идентификации , который в значительной степени самый скучный из возможных.
Однако, может иметь побочный эффект. Вы не спрашивали о побочных эффектах, только о возвращаемом значении, но давайте все равно посмотрим на это.
Поскольку each
должен просто возвращать свой получатель, в некотором смысле это также метод идентификации и, таким образом, чрезвычайно скучный. Однако , each
, как правило, должны оценивать передаваемый блок, передавая каждый элемент коллекции по очереди в качестве аргумента. Но он игнорирует значение, которое оценивает блок; блок оценивается исключительно по его побочному эффекту. Обратите внимание, что each
с блоком, который не имеет побочных эффектов, не имеет никакого смысла. Если у блока нет побочных эффектов, единственное, что интересно в блоке, это его значение, но each
игнорирует значение блока и просто возвращает self
.
foo.each do
# something that has no side-effect
end
полностью эквивалентно
foo
Другое соглашение Ruby заключается в том, что сообщение отправляет этот конец в вопросительном знаке ?
следует использовать для того, чтобы задавать вопросы (дух!) Т.е. отправка сообщения, заканчивающаяся знаком вопроса, должна возвращать то, что подходит для использования в качестве условия. У этого также вообще не должно быть побочного эффекта. (Это называется Принцип разделения команд и запросов и является фундаментальным принципом конструирования объектно-ориентированного программного обеспечения.)
И, наконец, унарный префиксный оператор !
, когда применяется к чему-то, что предназначено для использования в условном выражении (то есть булево значение или что-то эквивалентное), как правило, не имеет побочного эффекта. Следовательно, поскольку сообщение, отправляемое в блоке, заканчивается знаком вопроса, оно не должно иметь побочных эффектов, а оператор !
также не должен иметь побочных эффектов, поэтому можно предположить, что весь блок не имеет побочных эффектов.
Это, в свою очередь, означает, что each
не должен иметь побочного эффекта, и, следовательно, get_non_red_cats
не имеет побочного эффекта. В результате единственная другая вещь, которую get_non_red_cats
может сделать, это вернуть значение, и очень вероятно, что оно просто возвращает значение, которое было передано.
Ergo, весь метод эквивалентен
def get_non_red_cats(cats)
cats
end
Все это при условии , что автор следовал стандартным соглашениям Ruby. Если бы она этого не сделала, то этот метод мог бы сделать и вернуть что угодно вообще, он мог бы отформатировать ваш жесткий диск, запустить ядерную атаку, вернуть 42
или вообще ничего не делать.