Если в условии if
есть проверка responds_to?
, то в ветке then
тип переменной гарантированно будет ограничен теми типами, на которые отвечает этот метод:
if a.responds_to?(:abs)
# здесь тип a будет ограничен теми, на которые отвечает метод 'abs'
end
Кроме того, в ветке else
тип переменной гарантированно будет ограничен теми типами, на которые метод не отвечает:
a = some_condition ? 1 : "hello"
# a : Int32 | String
if a.responds_to?(:abs)
# здесь a будет Int32, поскольку Int32#abs существует, а String#abs нет
else
# здесь a будет String
end
Сказанное выше не работает с переменными объекта, класса и глобальными переменными. Для работы с ними присвойте их значение локальной переменной:
if @a.responds_to?(:abs)
# нельзя утверждать, что @a ответит на `abs`
end
a = @a
if a.responds_to?(:abs)
# здесь a гарантированно отвечает на `abs`
end
# Немного короче:
if (a = @a).responds_to?(:abs)
# здесь a гарантированно отвечает на `abs`
end