Search code examples
crystal-lang

variable type tagged additionally with Nil in ensure clause


I wonder why the type of the variable is (String | Nil) and not just String? Is there a way one can make it just String?

def main
  text = "hello"
ensure
  puts typeof(text) # => (String | Nil)
end

main

https://carc.in/#/r/2w3a


Solution

  • ensure runs after the main body in any case, even if there was an exception raised. Because this could have happend anywhere, it has to be considered that the body of the method hasn't been executed at all if it failed at the first instruction.

    Therefore, in the ensure block, all variables are known but it must be assumed that their value can be nil.

    If you're sure that text is always set, you don't need to protect that assignment in a rescue/ensure clause.

    def main
      text = "hello"
      begin
        # here is the code that might fail
      ensure
        puts typeof(text) # => String
      end
    end