Ruby의 인스턴스 변수 (@)
인스턴스 변수는 특정 객체에 속하며, 각 객체는 자신만의 고유한 복사본을 가집니다. 이는 객체별 상태를 저장하는 데 적합하며, Rails 모델이 개별 레코드를 다루는 방식과 유사합니다.
-
@로 시작하며, 인스턴스 메서드 내에서 접근 가능합니다. -
변경 사항은 해당 객체에만 영향을 미칩니다.
ruby
class User
def initialize(name); @name = name; end
def show; puts @name; end
end
user1 = User.new("Ahmed")
user2 = User.new("Sara")
Ruby의 클래스 변수 (@@)
클래스 변수는 클래스 자체에 속하며 해당 클래스의 모든 인스턴스 및 서브클래스 간에 공유됩니다.
-
@@로 시작하며, 변경 시 모든 인스턴스에 영향을 미칩니다. -
전역 카운터나 공유 설정에 사용될 수 있으나, 잘못 사용하면 예측 불가능한 부작용을 초래할 수 있습니다.
ruby
class User
@@count = 0
def initialize; @@count += 1; end
def self.total_users; @@count; end
end
클래스 변수의 위험성 및 Rails에서의 주의사항
Rails는 개발 모드에서 클래스 리로드와 멀티스레딩 환경을 가집니다. 클래스 변수는 모든 인스턴스와 서브클래스에 공유되므로, 예기치 않은 값 변경, 서브클래스에 의한 데이터 덮어쓰기, 멀티스레딩 문제 등을 야기할 수 있습니다.
ruby
class A; @@value = 100; end
class B < A; @@value = 200; end
이러한 특성은 대규모 Rails 애플리케이션에서 디버깅하기 어려운 버그로 이어질 수 있습니다.
권장되는 대안: 클래스 인스턴스 변수
Rails에서는 @@class_variable 대신 클래스 컨텍스트의 @variable(클래스 인스턴스 변수)을 공유 데이터 관리에 사용하는 것이 모범 사례입니다. 이는 서브클래스와 공유되지 않아 클래스 변수의 많은 단점을 회피할 수 있습니다.
ruby
class Config
@api_enabled = false
def self.api_enabled; @api_enabled; end
def self.enable_api; @api_enabled = true; end
end
이 방식은 Rails 설정 패턴에 이상적이며 더 안전하고 예측 가능한 공유 상태 관리를 가능하게 합니다.