Чтобы записать более кратко, вместо того, чтобы сделать это:
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
Этот плохой стиль? still-more-concise синтаксис:
do_something_with test_value if test_value = method_call_that_might_return_nil()
не позволяется, как обсуждено в другом ТАК вопрос, и останется тем путем в 1,9, по данным Matz (http://redmine.ruby-lang.org/issues/show/1141).
Учитывая возможный беспорядок присвоения и сравнения, это делает его слишком трудно для чтения кода?
Функционально-программирующим способом является использование и
. Это читабельный способ вызова метода цепочки, так что ноль в середине останавливает цепь. Таким образом, ваш пример будет что-то вроде:
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
Краткий код не обязательно лучше. Краткий код полезен, когда улучшает коммуникацию предполагаемого поведения кода от автора к будущим мейнтейнерам. Я думаю, что достаточно из прошлого, в котором у нас были случайные присваивания в блоках if
(когда мы имели в виду сравнение равенства), что мы предпочитаем стили, в которых совершенно ясно, что присваивание имеет в виду, а не сравнение. Уже упомянутая идиома .nil?
имеет это свойство, и я бы посчитал, что оно чище, чем иметь голое присваивание внутри условия if
. Впрочем, я не вижу вреда в том, чтобы иметь лишнюю строку кода для присваивания.
Программисты на Си это часто делают. Я тоже не вижу проблемы с этим в Ruby, пока понятно, что происходит
.Я думаю, это нормально. Обращение к присваиванию в условии происходит от осознания того, что пропущенный обход ключа при наборе == превращает сравнение в непреднамеренное присваивание. Стилистический запрет на использование присваивания в условии выделяет такие несчастные случаи как глаз (а иногда и язык, как в Си, где можно заставить многих компиляторов выдавать предупреждение, если они сталкиваются с присваиванием в условии). С другой стороны, тесты также выделяют такие несчастные случаи. Если Ваш код хорошо прошел тесты, то можно рассмотреть возможность отказа от таких запретов.
. Одна несколько распространенная идиома заключается в использовании и
, что выглядело бы примерно так:
tmp = method_call_that_might_return_nil and do_something_with tmp
Другой возможностью было бы назвать #ноль?
явно, таким образом намерение становится немного яснее; в частности, действительно очевидно, что вы на самом деле имели в виду назначить вместо сравнения:
unless (tmp = method_call_that_might_return_nil).nil?
do_something_with tmp
end
Да, я бы сказал, что это плохой стиль из-за возможной путаницы между заданием и сравнением. Это всего лишь еще одна строка для назначения, а затем проверки, и это позволяет избежать того, что кто-то в будущем подумает, что это ошибка, и исправит ее, чтобы использовать ==
вместо этого.