Why couldn't he write the first example like this? Relying on short-circuiting "or", I find this far more readable and maintainable than his final solution:
def get_cached_user(user_id=None, username=None):
"""
Returns a cached user object either by their user_id or by their username.
"""
user = (cache.get_user_by_id(user_id)
or cache.get_user_by_username(username)
or db.get_user_by_id(user_id)
or db.get_user_by_username(username))
if not user:
raise ValueError('User not found'))
cache.set_user(user, id=user.id, username=user.username)
return user
That's another great way to reduce nesting--factor it out into smaller more-focused functions. I came up with an intentionally contrived example to specifically induce nesting, but you're right that's a better way to write it.
Note that the "or" operator has some important downsides. For reducing bugs, using a COALESCE-like operator is IMHO more feasible. (see also: http://news.ycombinator.com/item?id=3415522)
Considering the semantics of the method (getting a user object or identifier), I don't think that's an issue. And a falsy OR also allows for using good (and falsy) null objects instead of nulls in object-oriented languages, an ability which would be lost (and lead to more reliance on NULLs, a behavior which should not be promoted) through a stricter selective operator.
The inability to trivially use null objects in conditionals is, in fact, one of the things I dislike in Ruby (where only `false` and `nil` are falsy).
Hm? How come? `or` is short-circuiting in the sense that when we have `a() or b()`, b() is only called if a() returns something falsy. Where would the issue arise?
Sure, abusing or in this way might seem hackish, but I feel like it's a net win for readability.