The following program fails to compile. What is the idiomatic way .
alias ANumber= Int32 | ::Nil
def addme(a : ANumber,b : ANumber) : ANumber
if ((a!=nil)&&(b!=nil))
a2=a.as(Int32)
b2=b.as(Int32)
a2+b2
else
nil
end
end
c=addme(2,3)
p c
d=addme(2,nil)
p d
def addme(a : Int32?, b : Int32?) : Int32?
return unless a && b
a + b
end
To handle nil you need to either use the special .nil? method, .try, or just check the variables directly as nil is a falsely value so the compiler can know they won’t be nil. != does not work because it’s possible to override it to return whatever, so the compiler cannot trust it.
Another way would be to have two overloads of the method, one only accepting Int32 and the other accepting Int32? with the former just being a + b and the latter nil return values.
a&&b and ((a!=nil)&&(b!=nil)) are not equivalent, as @Blacksmoke16 said, != is overloadable and can be return whatever, if you really like write code following your pattern, write like this:
def addme(a : Int32?, b : Int32?) : Int32?
if !a.nil? && !b.nil?
a2 = a.as(Int32)
b2 = b.as(Int32)
a2 + b2
else
nil
end
end
p! addme(2, nil) # => nil
Right, it’s a compile time error. rescue blocks can only handle runtime exceptions, not compile time errors.
FWIW you do not need the .as(Int32) the compiler is smart enough to do that for you, so can just do a + b in that branch as well. .as is mostly used when you have a value that could actually be say Int32 | String and you know its one or the other in a specific context the compiler can’t figure out; rather than using it to try and remove Nil.