Около двух с половиной лет я работал в среде Python 2.x на своей старой работе. После смены компании Ruby и Rails заменили Python и Flask. На первый взгляд языки не кажутся особо разными, но определенно есть общие идиомы Ruby, которые мне нужно было выучить.
При добавлении новой функции я наткнулся на такой код:
if (variable = some_func())
do_something(variable)
end
Интуитивно я догадался, что это означает «если some_func()
что-то возвращает, do_something
вместе с этим». Что заняло секунду, так это понимание того, что вы можете выполнять условные выражения присваивания.
Исходя из Python
В Python 2.x (и любом Python 3 до 3.8) присвоение переменной в условном выражении вернет синтаксическую ошибку:
>>> def some_func(): return 42;
...
>>> if (a = some_func())
File "<stdin>", line 1
if (a = some_func())
^
SyntaxError: invalid syntax
Скорее всего, присваивание в условном выражении — это опечатка, где программист хотел вместо этого сделать сравнение ==
.
Этот тип опечатки является достаточно серьезной проблемой, поэтому существует стиль программирования под названием Условия Йоды, в котором постоянная часть сравнения помещается в левую часть оператора. Это вызвало бы синтаксическую ошибку, если бы вместо ==
использовалось =
, например:
if (42 = x)
...
Назад к Руби
Теперь, когда я впервые столкнулся с такого рода присваиваниями в Ruby, я задумался, являются ли присваивания в условных выражениях хорошим стилем. Разумеется, в Руководстве по стилю Ruby есть раздел Безопасное назначение в условии . Раздел и примеры короткие и понятные. Вы должны взглянуть, если эта идиома Ruby нова для вас!
Что интересно в этой идиоме, так это то, что присваивание должно быть заключено в круглые скобки. Взгляните на примеры из Руководства по стилю Ruby:
# 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
Почему первый пример плохой? Что ж, в Руководстве по стилю также сказано, что не следует заключать условные выражения в скобки. Скобки вокруг присваиваний в условных выражениях специально вызываются как исключение из этого правила.
Я предполагаю, что, применяя два разных соглашения, одно для чистых условных выражений, а другое для присваиваний в условных выражениях, теперь ответственность за решение того, что они хотят сделать, ложится на программиста. Это должно предотвратить опечатки, когда присваивание =
используется вместо сравнения ==
, или наоборот.
Эквивалент Python
Как упоминалось выше, присваивания в условных выражениях возможны в Python 3.8 через PEP 572. Вместо использования an=
для таких назначений PEP ввел новый оператор :=
. Поскольку круглые скобки более распространены в выражениях Python, введение нового оператора :=
(неофициально известного как оператор моржа!!), вероятно, было решением Python для проблемы с опечатками.
Первоначально опубликовано на https://julienchien.com.