Ruby 인스턴스 변수가 어떻게 동작하는지, 왜 유용한지 배우고 싶으시다면 잘 찾아오셨습니다.
그럼 첫 번째 질문부터 시작해 보겠습니다.
인스턴스 변수란 무엇일까요?
Ruby에서 인스턴스 변수(instance variable)는 @ 기호로 시작하는 변수를 의미합니다.
예시:
@fruit
인스턴스 변수는 객체 지향 프로그래밍(OOP)에서 각 객체가 데이터를 저장할 수 있는 자신만의 private 공간을 갖도록 해주는 역할을 합니다.
흔히 객체는 다음과 같이 표현됩니다:
- 무언가를 수행한다 (Do things)
- 무언가를 알고 있다 (Know things)
메서드는 작업을 실행합니다. 즉, '수행(Do)'하는 역할입니다.
반면 인스턴스 변수는 데이터를 저장합니다. 즉, '알고(Know)' 있는 역할입니다.
예시:
Fruit(과일) 클래스가 있다면, 해당 과일의 종류, 색상, 무게 같은 정보를 알고 싶을 것입니다.
이런 속성들이 모두 인스턴스 변수가 됩니다.
예를 들어 @color, @type, @weight와 같은 형태죠.
이제 실제 코드 예제를 살펴보겠습니다.
Ruby 인스턴스 변수 정의 및 사용 방법
인스턴스 변수는 클래스 내부에서 정의합니다.
예시:
여기 CoffeeMachine(커피 머신) 클래스가 있다고 가정해 봅시다.
커피 머신은 물이 필요하므로, 탱크에 물이 얼마나 남아 있는지 알아야 할 것입니다.
이렇게 구현할 수 있습니다:
class CoffeeMachine
def initialize
@water = 100
end
end
여기서 @water가 바로 인스턴스 변수입니다.
@water에 초기값으로 100을 할당했습니다.
이제 make_coffee 메서드를 추가하면, 커피를 만들 때마다 남은 물의 양을 줄일 수 있습니다.
class CoffeeMachine
def initialize
@water = 100
end
def make_coffee
@water -= 10
end
end
주목할 점은, new로 생성한 모든 CoffeeMachine 객체가 각각 자신만의 독립적인 @water 값을 가진다는 것입니다.
이해가 되시나요?
실제 커피 머신이 10대 있다면, 각 머신마다 물의 양이 다를 테니까요.
바로 이런 이유 때문에 우리는 인스턴스 변수를 사용하는 것입니다!
인스턴스 변수에 접근하는 방법
현재 값을 읽을 수 없다면 인스턴스 변수는 큰 의미가 없습니다.
@ 문법을 사용하면 인스턴스 변수의 값을 읽을 수 있습니다.
다음과 같이요:
class CoffeeMachine
def initialize
@water = 50
end
def print_water_level
puts "Water Level: #{@water}"
end
end
machine = CoffeeMachine.new
machine.print_water_level
# Water Level: 50
print_water_level 메서드는 @water를 사용해 그 값을 출력합니다.
애트리뷰트 리더(attr_reader) 활용하기
클래스 외부에서는 인스턴스 변수에 직접 접근할 수 없다는 점을 눈치채셨을 겁니다.
이것은 의도된 설계입니다!
이를 '캡슐화(Encapsulation)'라고 부르며, 객체의 데이터가 외부의 다른 Ruby 객체들로부터 보호되는 것을 의미합니다.
직접 확인해 볼까요:
machine = CoffeeMachine.new
machine.water
# NoMethodError: undefined method `water' for #<CoffeeMachine:0x2d0a530>
machine.@water
# SyntaxError: unexpected tIVAR, expecting '('
경우에 따라서는 외부 접근을 허용하고 싶을 수도 있습니다.
객체의 데이터에 창문을 열어 외부에서도 접근 가능하게 만드는 것이죠.
한 가지 방법은 다음과 같습니다:
class CoffeeMachine
def initialize
@water = 100
end
def water
@water
end
end
machine = CoffeeMachine.new
machine.water
# 100
특별한 것은 없습니다.
접근 권한이 있는 클래스 내부에서 값을 반환하는 것뿐입니다.
또 다른 방법으로는 애트리뷰트 리더(attribute reader)를 사용하는 것입니다.
예시:
class CoffeeMachine
attr_reader :water
def initialize
@water = 100
end
end
machine = CoffeeMachine.new
machine.water
# 100
결과는 앞선 예제와 동일합니다.
차이점이라면 Ruby가 대신 water 메서드를 자동으로 생성해 준다는 것뿐입니다.
꼭 알아두어야 할 사항들
인스턴스 변수와 관련해 문제를 피하려면 몇 가지 기억해야 할 사항이 있습니다.
메모해 두세요:
- 정의되지 않은 인스턴스 변수는 항상
nil을 반환합니다 - 인스턴스 변수는 반드시
initialize메서드에서 생성해야 하는 것은 아니지만, 초기값을 부여하는 가장 일반적인 방법입니다 instance_variable_get처럼 인스턴스 변수에 접근하는 고급 방법도 있지만, 이러한 방식은 피하는 것이 좋습니다
참고로, 인스턴스 변수 목록을 조회할 수도 있습니다.
다음과 같이요:
machine.instance_variables # [:@water]
유용하게 활용하실 수 있을 겁니다 🙂
한 가지 더:
Rails에서는 인스턴스 변수(예: @books)를 컨트롤러와 뷰 사이에 데이터를 전달하는 용도로 사용합니다.
하지만 여러분이 직접 만든 클래스에서도 평소처럼 자유롭게 사용할 수 있습니다.
마무리
지금까지 Ruby 인스턴스 변수에 대해 알아보았습니다! @ 기호로 시작하며, 클래스 내부에서 데이터를 저장할 공간을 제공하는 변수입니다.
이제 직접 연습해 보는 것을 잊지 마세요. 예제 코드를 다뤄보고, 자신만의 코드를 만들어 보시길 바랍니다.
읽어주셔서 감사합니다.