For around two and a half years, I had been working in a Python 2.x environment at my old job . Since switching companies, Ruby and Rails has replaced Python and Flask. At first glance, the languages don’t seem super different, but there are definitely common Ruby idioms that I needed to learn.
While adding a new feature, I came across code that looked like this:
if (variable = some_func()) do_something(variable) end
Intuitively, I guessed this meant “if
some_func() returns something,
do_something with it.” What took a second was understanding that you could do an assignment conditional expressions.
Coming from Python
In Python 2.x land (and any Python 3 before 3.8), assigning a variable in a conditional expression would return a syntax error:
>>> def some_func(): return 42; ... >>> if (a = some_func()) File "<stdin>", line 1 if (a = some_func()) ^ SyntaxError: invalid syntax
Most likely, the assignment in a conditional expression is a typo where the programmer meant to do a comparison
This kind of typo is a big enough issue that there is a programming style called Yoda Conditionals
, where the constant portion of a comparison is put on the left side of the operator. This would cause a syntax error if
= were used instead of
==, like this:
if (42 = x) ...
Back to Ruby
Now that I’ve come across this kind of assignment in Ruby for the first time, I searched whether assignments in conditional expressions were good style. Sure enough, the Ruby Style Guide has a section called “Safe Assignment in Condition” . The section and examples are short and straightforward. You should take a look if this Ruby idiom is new to you!
What is interesting about this idiom is that the assignment should be wrapped in parentheses. Take a look at the examples from the Ruby Style Guide:
# 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
Why is the first example bad? Well, the Style Guide also says that you shouldn’t put parentheses around conditional expressions . Parentheses around assignments in conditional expressions are specifically called out as an exception to this rule.
My guess is that by enforcing two different conventions, one for pure conditionals and one for assignments in conditionals, the onus is now on the programmer to decide what they want to do. This should prevent typos where an assignment
= is used when a comparison
== was intended, or vice versa.
The Python Equivalent
As called out above, assignments in conditional expressions are possible in Python 3.8 via PEP 572
. Instead of using an
= for these kinds of assignments, the PEP introduced a new operator
:=. As parentheses are more common in Python expressions, introducing a new operator
:= (informally known as “the walrus operator”!!) was probably Python’s solution to the typo issue.