Является ли назначение в условной статье хорошим рубиновым стилем?
Чтобы писать более кратко, а не делать это:
test_value = method_call_that_might_return_nil()
if test_value
do_something_with test_value
end
Я назначил в условном выражении
if test_value = method_call_that_might_return_nil()
do_something_with test_value
end
Это плохой стиль? Еще более сжатый синтаксис:
do_something_with test_value if test_value = method_call_that_might_return_nil()
не разрешено, как обсуждалось в другом вопросе SO, и останется таким же в 1.9, согласно Matz (http://redmine.ruby-lang.org/issues/show/1141).
Учитывая возможную путаницу присвоения и сравнения, делает ли это слишком трудным для чтения код?
Ответы
Ответ 1
Это хороший стиль, чтобы использовать назначения в условных выражениях. Если вы это сделаете, оберните условие в скобки.
# bad (+ a warning)
if v = array.grep(/foo/)
do_something(v)
# some code
end
# good (MRI would still complain, but RuboCop won't)
if (v = array.grep(/foo/))
do_something(v)
# some code
end
# good
v = array.grep(/foo/)
if v
do_something(v)
# some code
end
Для получения дополнительной информации см. руководство по стилю сообщества.
Ответ 2
Одна из распространенных идиом заключается в использовании and
, который будет выглядеть примерно так:
tmp = method_call_that_might_return_nil and do_something_with tmp
Другая возможность заключалась бы в том, чтобы явным образом называть #nil?
, таким образом, намерение становится немного яснее; в частности, действительно очевидно, что вы на самом деле хотели назначить вместо сравнения:
unless (tmp = method_call_that_might_return_nil).nil?
do_something_with tmp
end
Ответ 3
Краткий код не обязательно лучший код. Конкретность полезна, когда она улучшает связь предполагаемого поведения кода с автором для будущих сопровождающих. Я думаю, что из нас достаточно опыта, из-за которых у нас были случайные назначения в блоках if
(когда мы хотели иметь сравнение равенства), что мы предпочитаем стили, в которых совершенно ясно, что назначение предназначено, а не сравнение. Уже упомянутая идиома .nil?
имеет это свойство, и я считаю ее более чистым, чем простое назначение внутри условия if
. Действительно, я не вижу вреда в наличии дополнительной строки кода для назначения.
Ответ 4
Функционально-программирующий способ сделать это - использовать andand
. Это читаемый способ вызова метода цепочки, так что ниль в середине останавливает цепочку. Таким образом, ваш пример будет примерно таким:
method_call_that_might_return_nil.andand.tap {|obj| do_something_with obj}
## or, in the common case: ##
method_call_that_might_return_nil.andand.do_something
Ответ 5
Да, я бы сказал, что это плохой стиль из-за возможной путаницы между назначением и сравнением. Это еще одна строка для назначения, а затем проверки, и это позволяет избежать того, что кто-то в будущем подумает, что это ошибка, и исправить ее вместо ==
.
Ответ 6
Программисты C делают это очень много. Я не вижу проблемы с этим в Ruby, пока он не выяснит, что происходит.
Ответ 7
Думаю, все в порядке. Отвращение к присваиванию в состоянии происходит от знания того, что штрих пропущенного ключа при вводе == превращает сравнение в непреднамеренное присвоение. Стилистический запрет на использование присваивания в состоянии делает такие аварии похожими на глаза (а иногда и на язык, как на C, где многие компиляторы могут быть сделаны, чтобы выпустить предупреждение, если они сталкиваются с назначением в состоянии). С другой стороны, тесты также вызывают такие аварии. Если ваш код хорошо освещен в тестах, вы можете отказаться от таких запретов.