if var.responds_to?(...)

if var.responds_to?(...)

if의 조건이 responds_to? 테스트라면, then 브랜치에서 변수의 타입은 그 메서드에 응답하는 타입들로 제한된다는 게 보장돼요:

if a.responds_to?(:abs)
  # here a's type will be reduced to those responding to the 'abs' method
end

추가로, else 브랜치에서는 변수의 타입이 그 메서드에 응답하지 않는 타입들로 제한된다는 게 보장돼요:

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

if a.responds_to?(:abs)
  # here a will be Int32, since Int32#abs exists but String#abs doesn't
else
  # here a will be String
end

위 방법은 인스턴스 변수나 클래스 변수에는 동작하지 않아요. 이들을 사용하려면 먼저 변수에 대입하세요:

if @a.responds_to?(:abs)
  # here @a is not guaranteed to respond to `abs`
end

a = @a
if a.responds_to?(:abs)
  # here a is guaranteed to respond to `abs`
end

# A bit shorter:
if (a = @a).responds_to?(:abs)
  # here a is guaranteed to respond to `abs`
end

출처: Crystal 공식 문서

더 알아보기 (Learn more)

  • 타입을 좁히는 다른 패턴은 if var.is_a?(...) 문서를 확인해 보세요.