Comment on page
루비 객체와 클래스
'루비를 깨우치다' 책의 5장을읽고 정리했습니다.
모든 루비 객체는 클래스 포인터와 인스턴스 변수 배열의 조합이다.
- 모든 루비 프로그램은 일련의 객체들과 이들 객체 간에 전달되는 메시지로 구성된다.
- 그렇다면 루비 객체란 무엇인가? 하나의 객체는 어떤 정보를 가지는가? 현미경을 통해서 하나의 루비 객체를 들여다 본다면 무엇을 알게 될까? 루비 클래스는 또 무엇인가? 등의 물음을 여기서 해결해보자
- 루비는 작성한 객체를
RObject
라는C 구조체
에 저장한다. - 그림의 상단에는
Robject
구조체에 대한 포인터가 위치한다. 내부적으로 루비는 항상 VALUE 포인터로 값을 참조한다. RObject
는RBasic 구조체
와객체 전용 정보
를 포함하고 있다.RBasic
은 다양한 내부 값을 저장하는flags
라는 불리언 값들과 klass 라는 하나의 클래스 포인터를 포함한다.- 클래스 포인터(klass)느 객체가 어떤 클래스의 인스턴스인지 알려준다.
- 루비는 각각의 객체가 포함하는 인스턴스 변수들의 배열을
RObject
에 저장한다.numiv
는 객체가 포함하는 인스턴스 변수의 개수ivptr
을 인스턴스 배열을 가리키는 포인터다.
- 여기서 1차적으로 루비의 객체 구조를 기술적인 용어로 정의해보자.
모든 루비 객체는 하나의 클래스 포인터와 인스턴스 변수의 배열을 조합한 것이다.
- 하지만 ... 이런 정의는 그리 유용하지 않다. 객체 뒤에 숨어있는 의미나 목적을 이해하거나 사용하는데 도움이 되지 못하기 때문이다.
- 간단한 루비 프로그램을 만들어서 살펴보자
- # 목록 5-1 : 간단한 루비 클래스class Mathematicianattr_accessor :first_nameattr_accessor :last_nameend
- 위의 클래스를 가지고 irb에서 테스트를 해보자
- # 목록 5-2eular = Mathematician.neweular# 결과# <Mathematician:0x00007fac99a40dd8>
- eular은
Mathematician
의 객체다. 이 객체 상태를 출력한 결과#<Mathematician:0x00007fac99a40dd8>
가 나왔다. 이 구문은 우리에게 두 가지를 알려준다.- 1.
Mathematician
은 클래스 포인터(klass
)다 - 2.
0x00007fac99a40dd8
은 해당 객체애 대한VALUE
포인터다.
- # 목록 5-3eular.first_name = 'Leonhard'# <Mathematician:0x00007fac99a40dd8 @first_name="Leonhard">eular.last_name = 'Eular'# <Mathematician:0x00007fac99a40dd8 @first_name="Leonhard", @last_name="Eular">
- 루비는 목록 5-3처럼 특정 객체에 저장하는 값들을 유지하기 위해서 인스턴스 배열을 사용한다.
- 아래의 코드를 실행할 때 루비는 하나의
RClass
구체와 두 개의RObject
구조체를 만들게 된다.
class Mathematician
attr_accessor :first_name
attr_accessor :second_name
end
# RClass: Mathematician
eular = Mathematician.new
eular.first_name = 'Leonhard'
eular.last_name = 'Eular'
# RObject: eular
euclid = Mathematician.new
euclid.first_name = 'Euclid'
# RObject: euclid
-
- 각각의
klass
값은 동일한Mathematician RClass
구제초를 가리키게 되며 각각의RObject
구조체는 각기 다른 인스턴스 변수의 배열을 가리킨다.
- 위의
Mathematician
클래스와 같이 직접 작성하는 클래스는RObject
구조체에 저장된다. - 하지만 루비의 일반 데이터형은 어떻게 되는걸까? (루 비의 일반 데이터형 또한 클래스의 객체다!)
- 그렇다면 일반데이터도
RObject
에 저장 되는걸까?- 아니다! 루비는 일반 데이터형을 저장하기 위해
RObject
가 아닌 다른 구조체를사용 한다. - `RObject는 개발자가 직접 작성한 클래스 인스턴스와 루비가 내부적으로 만드는 몇 가지 객체 클래스를 저장할 때에만 사용된다!!
- 예를 들어
String
의 경우는RString
, 정규표현식은RRegexp
구조체를 사용한다.
- 퍼포먼스를 생각하면 위와 같은
RObject
구조체를 모든 객체가 갖는다는건 말이 안된다. 예를 들어 간단한 숫자 1을 생각해보자. 1 또한 루비에서는객체
(메서드를 갖음)가 된다. - 당연하게도 루비에서는 최적화 방안으로 작은 정수, 심볼, 그리고 몇가지 간단한 값의 경우에는 어떠한 구조체의 도움도 받지 않는다.
- 루비 객체의 정의를 다시 생각해보자모든 루비 객체는 클래스 포인터와 인스턴스 변수 배열의 조합이다.
- 일반 객체에 대한 인스턴스 배열? 그렇다면 정수, 문자열, 그 외 일반적인 데이터 값들은 인스턴스 배열을 갖는건가?
- 뭔가.. 상식적으로 아닐거 같다.
- 하지만 정수와 문자열 등이 객체라면 인스턴스 변수