Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Ruby에서 변수가 정의되었는지 확인하는 방법 (defined? 완벽 가이드)

Ruby에는 변수가 정의되어 있는지 확인할 수 있는 defined? 키워드가 있습니다.

변수가 존재하면 해당 변수의 타입을 반환합니다:

apple = 1

defined?(apple)
# "local-variable"

존재하지 않으면 nil을 반환합니다:

defined?(bacon)
# nil

이는 JavaScript의 typeof 연산자와 비슷한 역할을 합니다. 만약 객체의 클래스를 알고 싶다면 defined? 대신 class 메서드를 사용하는 것이 좋습니다.

defined?에 대해 기억해 둘 만한 흥미로운 특징들이 있습니다:

  • defined?는 메서드가 아닌 키워드(keyword)입니다
  • defined?는 이름 끝에 물음표(?)가 붙지만, Ruby의 일반적인 관례와 달리 truefalse를 반환하지 않는 몇 안 되는 요소 중 하나입니다
  • defined?는 값이 nil인 변수와 한 번도 설정된 적 없는 변수를 구분할 수 있습니다

이러한 특별한 속성들 때문에 이 키워드를 제대로 배워둘 가치가 충분합니다.

정의된 변수를 확인하는 더 나은 방법

defined? 키워드는 유용하지만 몇 가지 문제점이 있습니다.

왜 그럴까요?

연산자 우선순위(operator precedence)가 낮기 때문입니다.

예를 들어 다음과 같은 코드를 작성하면:

defined? orange && orange.size

결과는 "expression"이 됩니다.

orange && orange.size 전체가 defined?의 인자로 해석되기 때문입니다.

올바른 작성 방법은 다음과 같습니다:

defined?(orange) && orange.size

Ruby에는 변수가 정의되었는지 확인할 수 있는 다른 방법들도 있습니다.

지역 변수(local variable)의 경우:

local_variables.include?(:orange)

인스턴스 변수(instance variable)의 경우:

instance_variable_defined?("@food")

하지만 사실 이런 방법들은 사용할 필요가 거의 없습니다.

99%의 경우, 지역 변수가 존재하지 않는다면 오타가 있거나 누군가 변수 선언을 잊어버린 것입니다.

그렇다면 인스턴스 변수는 어떨까요?

정의되지 않은 인스턴스 변수는 항상 nil을 반환하므로, nil 여부를 확인하는 것이 좋습니다.

이럴 때 "안전 내비게이션 연산자(safe navigation operator)"(Ruby 2.3+)를 활용해 보세요. 이 연산자는 변수가 nil이 아닐 때만 메서드를 호출합니다.

예시는 다음과 같습니다:

if @user&.country == "Spain"
  # ...
end

이 코드는 아래와 동일하게 동작합니다:

if @user && @user.country == "Spain"
  # ...
end

이 방법들은 defined? 키워드만큼 범용적이지는 않지만, 더 예측 가능하고 오류 발생 가능성이 낮다는 장점이 있습니다.

메서드가 정의되어 있는지 확인하기

defined?를 사용해 메서드의 정의 여부를 확인할 수도 있지만, 실용성은 떨어집니다.

예시:

defined?(puts)
# "method"

defined?는 메서드가 아닌 키워드이기 때문에 객체와 함께 사용할 수 없습니다.

즉, 다음과 같은 코드는 에러를 발생시킵니다:

[].defined?(:size)
# undefined method `defined?' for []:Array

메서드 존재 여부를 확인하려면 respond_to? 메서드를 사용해야 합니다.

사용 방법은 다음과 같습니다:

[].respond_to?(:size)
# true

[].respond_to?(:orange)
# false

클래스가 존재하는지 확인하기

예시:

defined?(Object)
# "constant"

defined?(A)
# nil

클래스(상수)의 존재 여부를 확인할 때는 const_defined? 메서드를 사용하는 것이 더 좋습니다.

다음과 같이 사용합니다:

Object.const_defined?(:String)
# true

Object.const_defined?(:A)
# false

정리

지금까지 특정 변수, 클래스 또는 메서드가 존재하는지 확인하는 쉬운 방법들을 살펴보았습니다!

변수를 다룰 때 대부분의 상황에서 실제로 필요한 것은 변수가 정의되었는지 여부가 아니라 nil인지 확인하는 것입니다. 아니면 더 나아가, 변환 메서드를 사용해 변수를 특정 클래스로 변환하는 것도 좋은 접근입니다.

이 글이 도움이 되셨기를 바랍니다! 유용했다면 공유해 주셔서 더 많은 사람들이 볼 수 있게 해주세요.