For example, if we want to check an array is either nil or empty, we can write as follows:
if !a || a.empty?
puts "nil or empty!"
end
#-> OK
however, if we want to check two arrays in the same way, an error occurs:
if !a || !b || a.empty? || b.empty?
puts "nil or empty!"
end
#-> Error, `undefined method 'empty?' for Nil`
# in the expression `a.empty?`
Swapping the position of !b
and a.empty?
doesn't help, but different place is pointed to as an error:
if !a || a.empty? || !b || b.empty?
puts "nil or empty!"
end
#-> Still error, `undefined method 'empty?' for Nil`
# but this error is in the expression `b.empty?`
Why in this (multiple variable's) case compiler can't infer that a
and b
are non-nil when a.empty?
and b.empty?
are called, respectively?
The whole reproducible code is following.
def foo (flag)
if flag
[] of Int32
else
nil
end
end
# note, foo returns `Array(T) | Nil`
a = foo(true)
b = foo(true)
if !a || a.empty?
puts "nil or empty!"
end
#-> OK
if !a || !b || a.empty? || b.empty?
puts "nil or empty!"
end
#-> Error, `undefined method 'empty?' for Nil`
# in the expression `a.empty?`
if !a || a.empty? || !b || b.empty?
puts "nil or empty!"
end
#-> Still error, `undefined method 'empty?' for Nil`
# but this error is in the expression `b.empty?`
It seems like a compiler bug.
But you can just put the conditions in parenthesis to make it work: (!a || a.empty?) || (!b || b.empty?)