Entry
Cascading IFs for re.match
Jul 5th, 2000 09:59
Nathan Wallace, Hans Nowak, Snippet 91, Tim Peters
"""
Packages: text.regular_expressions
"""
"""
> Unfortunately, it proved to be too specific and therefore fooled people
> such a yourself into finding superior ways of solving that particular
> problem instead of addressing the general case. Consider instead the
> following:
>
> if meets_cond1(f_value := f1()):
> # use f_value returned by f1()
> elif (f_value := a * 3 + f2()) > cv2():
> # use f_value from expression
> ...
> elif (f_value := f_value + 2) > 20:
> # use f_value from last "elif" plus 2
> else:
> # give up
>
> Hopefully this more eclectic formulation communicates the problem clearly.
> Without ":=" or equivalent, the coder is forced to use "while 1/break",
> endlessly nested "if"s, or some other unpleasant workaround.
Thanks for explaining it, Evan! Just to make the record complete, I'll trot
out what's probably both the cleanest and sickest <0.5 wink> workaround for
the crushingly-general case:
"""
class Done: pass
try:
f_value = f1()
if meets_cond1(f_value):
# use f_value returned by f1()
raise Done
f_value = a * 3 + f2()
if f_value > cv2():
# use f_value from expression
raise Done
f_value = f_value + 2
if f_value > 20:
# use f_value from last "elif" plus 2
raise Done
# give up
except Done:
pass
"""
Really the same as wrapping it in a one-trip loop and spelling goto "break"
instead of "raise". Except that instead of being mislead into thinking
there's a loop, the reader is fooled into thinking the code has something to
do with recoverable errors.
When possible, it's often best to stuff such hairy logic into a helper
function and spell goto "return". Then the reader is just tricked into
thinking there's a reusable abstraction ...
when-you-can't-say-what-you-mean-you-don't-mean-what-you-say-ly y'rs - tim
"""