if var

if의 조건이 변수라면, then 분기 안에서 그 변수는 Nil 타입을 갖지 않는 것으로 취급됩니다.

a = some_condition ? nil : 3
# a는 Int32 혹은 Nil

if a
  # a가 참이어야 하기 때문에
  # a는 nil일 수 없으므로
  # 이때 a는 Int32
  a.abs
end

if의 조건문에서 변수가 할당될 때에도 적용됩니다.

if a = some_expression
  # a는 nil이 아님
end

조건에 &&가 있을 때에도 똑같이 적용됩니다.

if a && b
  # a와 b는 모두 nil이 아님
end

이때 && 표현식의 우측에서도 aNil이 아니라는 것이 보장됩니다.

물론 then 분기 안에서 변수를 다시 할당한다면 그 변수는 할당된 표현식에 따라 새로운 타입을 갖게 됩니다.

하지만 이는 인스턴스 변수나 클래스 변수에는 적용되지 않습니다.

if @a
  # 이때 @a는 nil일 수 있음
end

이는 어떠한 메서드 호출이라도 잠재적으로 해당 변수를 건드릴 수 있기 때문입니다. 뿐만 아니라 조건을 확인한 다음 다른 스레드가 그 인스턴스 변수를 바꿀 수도 있습니다.

@anil이 아닐 때에만 이용하려면 두 가지 방법이 있습니다.

  # 첫 번째: 변수에 할당
if a = @a
  # a는 nil이 아님
end

# 두 번째: 표준 라이브러리의 `Object#try`를 이용
@a.try do |a|
  # a는 nil이 아님
end

게터나 속성 등 프록이나 메서드를 호출할 때에도 마찬가지입니다. nil이 될 수 있는 (혹은 공용체 타입인) 프록과 메서드는 두 번 이상 연속으로 호출했을 때 같은 값을 반환한다는 보장이 없기 때문입니다.

if method # 첫 호출은 Int32 혹은 Nil을 반환
  # 첫 호출은 Nil을 반환하지 않았음
  method # 그러나 두 번째 호출은 Int32 혹은 Nil을 반환
end

위에서 본, 인스턴스 변수를 다루는 기법을 프록 및 메서드 호출에 적용할 수 있습니다.

results matching ""

    No results matching ""