if var.is_a?(...)

if var.is_a?(...) (타입 제약)

is_a? 검사가 if의 조건으로 쓰이면, then 분기(참인 경우)에서 변수의 타입이 그 타입으로 제약된다는 것이 보장돼요.

if a.is_a?(String)
  # here a is a String
end

if b.is_a?(Number)
  # here b is a 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)
  # here a is a String and b is a Number
end

그런데 인스턴스 변수나 클래스 변수에는 이 방식이 동작하지 않아요. 이런 변수들을 다루려면 먼저 변수에 대입해야 합니다.

if @a.is_a?(String)
  # here @a is not guaranteed to be a String
end

a = @a
if a.is_a?(String)
  # here a is guaranteed to be a String
end

# A bit shorter:
if (a = @a).is_a?(String)
  # here a is guaranteed to be a String
end

출처: Crystal 공식 문서 - if var.is_a?(...)

더 알아보기 (Learn more)