Bug #16631
Updated by prijutme4ty (Ilya Vorontsov) over 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.