Bug #16631
Updated by prijutme4ty (Ilya Vorontsov) almost 5 years ago
I've found that usual-if and postfix-if work differently when there is an assignment in condition. In both cases, a value is assigned to a variable, but in postfix-if left part doesn't have access to a variable if it is a local variable which was first defined in a condition. When a variable if defined everything goes as intended: ``` ruby lv_predefined = nil puts("lv_predefined inside postfix-if: `#{lv_predefined}`") if lv_predefined = 'some value' # lv_predefined inside postfix-if: `some value` puts("lv_predefined after postfix-if: `#{lv_predefined}`") # lv_predefined after postfix-if: `some value` ``` When a local variable is not defined, it *is* assigned but is unavailable in postfix-if body: ``` ruby puts("undef_lv_postfix inside postfix-if: `#{undef_lv_postfix}`") rescue 'error' if undef_lv_postfix = 'some value' # => error puts("undef_lv_postfix after postfix-if: `#{undef_lv_postfix}`") # undef_lv_postfix after postfix-if: `some value` ``` That's different from usual if, which defines a variable and make it available for its body: ``` ruby if lv_if = 'some value' puts("lv_if inside usual-if: `#{lv_if}`") end # lv_if inside usual-if: `some value` ``` To make things even more confusing, instance variable are immediately available in postfix-if unlike local variables. ``` ruby puts("@iv inside postfix-if: `#{@iv}`") if @iv = 'some value' # @iv inside postfix-if: `some value` puts("@iv after postfix-if: `#{@iv}`") # @iv after postfix-if: `some value` ``` I think this behavior doesn't meet the principle of least surprise. And here's a case where assignment in postfix-if is indeed useful. I wish to match some string against a pattern and extract some information from it, so I have the following code: ``` query = 'HGNC:1234' # query = 'MGI:5678' puts("human gene: #{match[1]}") if match = query.match(/HGNC:(\d+)/) puts("mouse gene: #{match[1]}") if match = query.match(/MGI:(\d+)/) ``` These two lines look identical but they are not (because `match` is an undefined local variable if this code was invoked from scratch). variable). For human genes this code raises an exception, for mouse genes it works as intended. Very subtle problem.