Язык программирования Crystal

if var.is_a?(...)

Если в условии if выполняется проверка is_a?, то переменная в ветке then гарантированно будет того типа, который указан в условии.

if a.is_a?(String)
  # здесь a будет String
end

if b.is_a?(Number)
  # здесь b будет Number
end

Однако в ветке else тип переменной не будет ограничен типом, указанном в условии:

a = some_condition ? 1 : "hello"
# a : Int32 | String

if a.is_a?(Number)
  # a : Int32
else
  # a : String
end

Обратите внимание, что при проверке is_a? можно использовать любой тип, в том числе абстрактные классы и модули.

Сказанное выше действует также при использовании логического И (&&) в условии:

if a.is_a?(String) && b.is_a?(Number)
  # здесь a будет String и b будет Number
end

Однако сказанное выше не работает с переменными объекта, класса и глобальными переменными. Для работы с ними сначала нужно присвоить их значение локальной переменной:

if @a.is_a?(String)
  # нельзя утверждать, что @a наверняка будет String
end

a = @a
if a.is_a?(String)
  # здесь a гарантированно будет String
end

# Более краткая запись:
if (a = @a).is_a?(String)
  # здесь a гарантированно будет String
end