Исходя из фона Python, где всегда есть «правильный способ сделать это» («Pythonic»), когда дело доходит до стиля, мне интересно, существует ли то же самое для Ruby. Я использовал свои собственные рекомендации по стилю, но я думаю о выпуске своего исходного кода, и я хотел бы, чтобы он придерживался любых неписаных правил, которые могли бы существовать.
Это "Рубиновый Путь" явно печатать return
в методах? Я видел, как это было сделано с и без, но есть ли правильный способ сделать это? Есть ли подходящее время, чтобы сделать это? Например:
def some_func(arg1, arg2, etc)
# Do some stuff...
return value # <-- Is the 'return' needed here?
end
ruby
coding-style
return-value
Саша Чедыгов
источник
источник
Ответы:
Старый (и «отвеченный») вопрос, но в ответ я добавлю два цента.
TL; DR - Вам не нужно, но в некоторых случаях это может сделать ваш код более понятным.
Хотя не использование явного возврата может быть «способом Ruby», это сбивает с толку программистов, работающих с незнакомым кодом, или незнакомых с этой функцией Ruby.
Это несколько надуманный пример, но представьте себе небольшую функцию, подобную этой, которая добавляет единицу к переданному числу и присваивает ее переменной экземпляра.
Это должна была быть функция, которая возвращала значение, или нет? Сложно сказать, что имел в виду разработчик, поскольку он назначает переменную экземпляра и возвращает возвращаемое значение.
Предположим, намного позже, другой программист (возможно, не очень хорошо знакомый с тем, как Ruby делает возвраты на основе последней выполненной строки кода) приходит и хочет вставить несколько операторов печати для регистрации, и функция становится такой ...
Теперь функция не работает, если что-либо ожидает возвращаемого значения . Если ничто не ожидает возвращаемого значения, это нормально. Ясно, что если где-то дальше по цепочке кода, что-то, вызывающее это, ожидает возвращаемое значение, оно потерпит неудачу, поскольку не вернет то, что ожидает.
Реальный вопрос сейчас заключается в следующем: ожидало ли что-нибудь возвращаемое значение? Это что-то сломало или нет? Это что-то сломает в будущем? Кто знает! Только полный просмотр кода всех звонков даст вам знать.
Так что для меня, по крайней мере, наилучший практический подход заключается в том, чтобы либо четко указать, что вы возвращаете что-то, если это имеет значение, либо вообще ничего не возвращать, если это не так.
Так что в случае нашей маленькой демонстрационной функции, предполагая, что мы хотим, чтобы она возвращала значение, она была бы написана так:
И любому программисту было бы очень ясно, что оно возвращает значение, и им гораздо сложнее его сломать, даже не осознавая.
В качестве альтернативы, можно написать это так и пропустить оператор return ...
Но зачем вообще опускать слово «вернуться»? Почему бы просто не вставить это туда и не дать на 100% понять, что происходит? Это буквально не повлияет на способность вашего кода выполнять.
источник
return
добавляет семантическое значение в код, почему бы и нет? Это вряд ли очень многословно - мы не говорим 5 строк против 3, просто еще одно слово. Я бы предпочел видетьreturn
хотя бы в функциях (возможно, не в блоках), чтобы выразить, что на самом деле делает код. Иногда вам нужно возвращать среднюю функцию - не пропускайте последнееreturn
ключевое слово в последней строке только потому, что можете. Я вообще не одобряю многословие, но я предпочитаю последовательность.side_effect()
и другой разработчик решает (ab) использовать неявное возвращаемое значение вашей процедуры. Чтобы это исправить, вы можете сделать ваши процедуры явноreturn nil
.Нет. Хороший стиль Ruby обычно использует только явные возвраты для раннего возврата . Ruby хорош в минимализме кода / неявной магии.
Тем не менее, если явное возвращение сделает вещи более понятными или более легкими для чтения, это ничего не повредит.
источник
return
уже имеет значительное семантическое значение как РАННИЙ ВЫХОД в функцию.return
последнюю строчку с РАННИМ ВЫХОДОМ ?Я лично использую
return
ключевое слово, чтобы различать то, что я называю функциональными методами , то есть методами, которые выполняются в основном для их возвращаемого значения, и процедурными методами , которые выполняются в основном для их побочных эффектов. Итак, методы, в которых возвращаемое значение важно, получают дополнительноеreturn
ключевое слово, чтобы привлечь внимание к возвращаемому значению.Я использую то же различие при вызове методов: функциональные методы получают круглые скобки, а процедурные - нет.
И последнее, но не менее важное, я также использую это различие с блоками: функциональные блоки получают фигурные скобки, процедурные блоки (то есть блоки, которые «делают» что-то) получают
do
/end
.Однако я стараюсь не быть религиозным по этому поводу: с блоками, фигурными скобками и
do
/end
иным приоритетом, и вместо того, чтобы добавлять явные скобки для устранения неоднозначности выражения, я просто переключаюсь на другой стиль. То же самое касается вызова метода: если добавление скобок вокруг списка параметров делает код более читабельным, я делаю это, даже если рассматриваемый метод носит процедурный характер.источник
На самом деле важно различать:
В Ruby нет собственного способа их различения, что делает вас уязвимым для написания процедуры,
side_effect()
а другой разработчик решает злоупотребить неявным возвращаемым значением вашей процедуры (в основном рассматривая его как нечистую функцию).Чтобы решить эту проблему, возьмите лист из книги Scala и Haskell и попросите явным образом вернуть ваши процедуры
nil
(иначеUnit
или()
на других языках).Если вы следуете этому, то использование явного
return
синтаксиса или не только становится вопросом личного стиля.Для дальнейшего различения функций и процедур:
do/end
()
, тогда как когда вы вызываете функции, неОбратите внимание, что Jörg W Mittag на самом деле выступал с другой стороны - избегая
()
s для процедур - но это не рекомендуется, потому что вы хотите, чтобы вызовы метода побочных эффектов были четко различимы от переменных, особенно когда arity равен 0. См. Руководство по стилю Scala для вызова метода для подробности.источник
function_a
, иfunction_a
было написано для вызова (и может работать только путем вызова)procedure_b
, тоfunction_a
действительно ли это функция? Он возвращает значение, отвечающее вашим требованиям к функциям, но имеет побочный эффект, удовлетворяющий требованиям процедур.function_a
может содержать деревоprocedure_...
вызовов, так как действительноprocedure_a
может содержать деревоfunction_...
вызовов. Подобно Scala, но в отличие от Haskell, в Ruby не может быть никакой гарантии, что функция не имеет побочных эффектов.Руководство по стилю гласит, что вы не должны использовать
return
в своем последнем утверждении. Вы все еще можете использовать его, если он не последний . Это одно из соглашений, которым строго следует сообщество, и вы должны, если вы планируете сотрудничать с кем-либо, использующим Ruby.При этом основной аргумент в пользу использования явных
return
s заключается в том, что это сбивает с толку людей, пришедших с других языков.Распространенной эвристикой для длины метода (исключая методы получения / установки) в Java является один экран . В этом случае вы можете не увидеть определение метода и / или уже забыли о том, откуда вы возвращались.
С другой стороны, в Ruby лучше придерживаться методов длиной менее 10 строк . Учитывая это, можно задаться вопросом, почему он должен писать на ~ 10% больше заявлений, когда они явно подразумеваются.
Так как в Ruby нет методов void, и все намного проще, вы просто добавляете накладные расходы ни для одного из преимуществ, если вы используете явные
return
s.источник
Я согласен с Беном Хьюзом и не согласен с Тимом Холтом, потому что в этом вопросе упоминается окончательный способ, которым Python делает это, и спрашивает, есть ли у Ruby аналогичный стандарт.
Оно делает.
Это настолько известная особенность языка, что любой, кто ожидал отладить проблему в ruby, должен был знать о ней.
источник
return
ключевое слово, когда в нем нет необходимости.Вопрос в том, какой стиль вы предпочитаете по большей части. Вы должны использовать ключевое слово return, если хотите вернуться откуда-то посередине метода.
источник
Как сказал Бен. Тот факт, что «возвращаемое значение метода ruby является возвращаемым значением последнего оператора в теле функции», приводит к тому, что ключевое слово return редко используется в большинстве методов ruby.
источник
if failed_check then nil else @list end
? Это действительно функционально .