Какова точка возврата в Ruby?

В чем разница между return и просто помещением переменной, например:

возврат не возвращается

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  mood
end

возвращение

def write_code(number_of_errors)
  if number_of_errors > 1
    mood =  "Ask me later"
  else
    mood = puts "No Problem"
  end  
  return mood
end

Ответ 1

return позволяет вам пробиваться рано:

def write_code(number_of_errors)
  return "No problem" if number_of_errors == 0
  badness = compute_badness(number_of_errors)
  "WHAT?!  Badness = #{badness}."
end

Если number_of_errors == 0, то "No problem" будет возвращено немедленно. Однако в конце метода это не нужно, как вы заметили.


Изменить: Чтобы продемонстрировать, что return выходит немедленно, рассмотрите эту функцию:

def last_name(name)
  return nil unless name
  name.split(/\s+/)[-1]
end

Если вы вызываете эту функцию как last_name("Antal S-Z"), она вернет "S-Z". Если вы называете его last_name(nil), он возвращает nil. Если return не прерывается немедленно, он попытается выполнить nil.split(/\s+/)[-1], что вызовет ошибку.

Ответ 2

Использование "return" не требуется, если это последняя строка, которая должна быть выполнена в методе, так как Ruby автоматически возвращает последнее вычисленное выражение.

Вам даже не нужно это окончательное "настроение", и вам не нужны эти назначения в инструкции IF.

def write_code(number_of_errors)
    if number_of_errors > 1
       "ERROR"
    else
       "No Problem"
    end  
end

puts write_code(10)

Выход:

ОШИБКА

Ответ 3

Я использую return, когда я просматриваю список, и я хочу выйти из функции, если любой член списка соответствует критериям. Я мог бы выполнить это с помощью одного утверждения, например:

list.select{|k| k.meets_criteria}.length == 0

в некоторых ситуациях, но

list.each{|k| return false if k.meets_criteria}

- тоже одна строка - на мой взгляд, добавлена ​​гибкость. Например, в первом примере предполагается, что это единственная строка в методе и что мы хотим вернуться с этого момента независимо от того, что. Но если это тест, чтобы убедиться, что безопасно продолжать работу с остальным методом, первый пример должен будет обрабатывать это по-другому.

EDIT:

Чтобы добавить некоторую гибкость, рассмотрите следующую строку кода:

list_of_method_names_as_symbols.each{|k| list_of_objects.each{|j| return k if j.send(k)}}

Я уверен, что это может быть достигнуто в одной строке, без return, но с верхней части моей головы я не вижу, как это сделать.

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

EDIT

Следует отметить, что я предполагаю, что эта строка находится внутри метода, а не блока.


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

Ответ 4

Ruby всегда возвращается! лучший способ -

def write_code(number_of_errors)
  (number_of_errors > 1)? "ERROR" : "No Problem"
end

это означает, что если number_of_errors > 1, он вернет ERROR else No Problem

Ответ 5

Хороший рубин дает эту хорошую возможность не указывать оператор return явно, но я просто чувствую, что в качестве стандартного программирования всегда нужно стремиться указывать "возвращаемые" утверждения везде, где это необходимо. Это помогает сделать код более читаемым для тех, кто приходит из разных источников, таких как С++, Java, PHP и т.д., И изучает рубин. Операция "return" ничего не навредит, поэтому зачем пропускать обычный и более стандартный способ возврата из функций.

Ответ 6

Одно маленькое предупреждение для тех, кто приходит с других языков. Допустим, у вас есть функция, подобная OP, и вы используете правило "последняя вещь вычисляется" для автоматической установки возвращаемого значения:

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
end

и допустим, вы добавили оператор отладки (или записи в журнал):

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  puts "### mood = #{mood}"
end

Теперь угадай, что. Вы нарушили свой код, потому что puts возвращает nil, который теперь становится возвращаемым значением из функции.

Решение состоит в том, чтобы привыкнуть всегда явно указывать возвращаемое значение в последней строке, как это делал OP:

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  puts "### mood = #{mood}"
  mood
end

Ответ 7

Unnecesarity return в последней строке в функции - это просто синтаксический сахар Ruby. В большинстве процедурных языков вам нужно написать return в каждой (не-void в С++) функции.