Ruby를 한동안 사용해 왔다면 내부에서 어떻게 작동하는지 궁금할 것입니다.
Ruby 내부를 깊이 파고드는 한 가지 방법은 Ruby가 작동하도록 하는 소스 코드를 읽는 것입니다. C를 모르더라도 흥미로운 것을 배울 수 있습니다.
소스 코드는 Ruby용 github 저장소에서 찾을 수 있습니다.
이상적으로는 클래스 및 메서드 이름을 쉽게 찾을 수 있는 Codequery와 같은 도구를 사용하는 것이 좋습니다.
핵심 클래스 탐색
대부분의 탐색은 루트 폴더에서 이루어집니다. 여기에서 Object
와 같은 모든 핵심 클래스의 소스 코드를 찾을 수 있습니다. object.c
에서 또는 Array
array.c
에서 .
hash.c
를 살펴보겠습니다. .
4468행까지 스크롤을 내리면 익숙한 이름이 보일 것입니다.
이것부터 시작하겠습니다 :
rb_cHash =rb_define_class("해시", rb_cObject);
이 줄에서 Hash
클래스가 rb_define_class
에 의해 정의되고 있습니다. 기능. 두 번째 인수(rb_cObject
)는 이 클래스의 슈퍼클래스입니다.
클래스 정의 프로세스가 어떻게 작동하는지 알고 싶다면 rb_define_class
를 검색하세요. .
rb_define_class
의 첫 번째 부분 클래스가 이미 정의되었는지 확인합니다.
if (rb_const_defined(rb_cObject, id)) { // ...}
그 if
내부 블록에서 Ruby는 이미 정의된 클래스로 작업하고 있는지 확인하는 등 몇 가지 온전한 검사를 수행합니다.
클래스가 정의되지 않은 경우 다음과 같이 정의됩니다.
klass =rb_define_class_id(id, super);st_add_direct(rb_class_tbl, id, klass);rb_name_class(klass, id);rb_const_set(rb_cObject, id, klass);rb_class_inherited(수퍼턴, klass)>이 모든 방법에 대한 정의를 읽을 수 있지만 꽤 자명하다고 생각합니다.
st_add_direct
에서 , 'st' 부분은 '기호 테이블'을 의미하며 이것은 단지 해시 테이블입니다.rb_const_set
함수는Object
에 상수를 설정합니다. 클래스를 사용하면 어디서나 사용할 수 있습니다.그리고
rb_class_inherited
inherited
호출 슈퍼클래스의 메서드에 대한 설명은 여기에서 찾을 수 있습니다.코드의 다음 섹션은 메서드 정의로 구성됩니다. MRI는
rb_define_method
를 사용합니다. 그렇게 하기 위해.예시입니다 :
rb_define_method(rb_cHash,"인덱스", rb_hash_index, 1);rb_define_method(rb_cHash,"크기", rb_hash_size, 0);rb_define_method(rb_cHash,"길이", rb_hash,"길이", rb_hash,"길이", rb_hash_size, 0 , rb_hash_empty_p, 0);인수는 다음과 같습니다. :
- 첫 번째 인수는 이 메서드가 정의되는 클래스입니다.
- 두 번째 인수는 메서드 이름이고, 세 번째 인수는 이 메서드를 실제로 구현하는 C 함수입니다.
- 마지막 인수는 이 Ruby 메서드에 필요한 인수의 수입니다(음수 값은 선택적 인수를 의미합니다)
rb_define_singleton_method
함수는 클래스 메서드를 정의하는 데 사용됩니다.
rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
rb_define_singleton_method
의 본문 한 줄의 코드일 뿐입니다:
rb_define_method(singleton_class_of(obj), 이름, func, argc);
계속 탐색하려면 object.c
를 살펴보는 것이 좋습니다. .
표준 라이브러리 탐색
자, 오늘 C로 충분합니다!
Ruby 코드를 읽는 것은 어떻습니까?
Ruby 표준 라이브러리는 Ruby로 작성되었으며 /lib
에서 찾을 수 있습니다. 디렉토리.
표준 라이브러리에는 OpenStruct, Base64
와 같은 항목이 포함되어 있습니다. 인코딩 및 Set
데이터 구조.
집합은 배열과 유사하지만 모든 요소가 고유하다는 특별한 속성이 있습니다. 즉, 세트에 중복 항목이 없습니다.
어떻게 작동합니까? 이 뒤에 멋진 알고리즘이 있습니까?
set.rb
를 살펴보면 이것이 Hash
에 의해 뒷받침된다는 것을 빨리 알게 될 것입니다. 개체.
# 주어진 객체를 집합에 추가하고 self를 반환합니다. +merge+를 사용하여 # 한 번에 많은 요소를 추가합니다.def add(o) @hash[o] =true selfendalias <따라서 중복된 요소를 추가하면 이미 존재하는지 확인할 필요가 없으며 기존 요소를 덮어쓰기만 하면 됩니다.
루비니우스 탐색
Ruby의 소스 코드를 탐색하는 또 다른 방법은 Rubinius와 같은 대체 구현을 살펴보는 것입니다.
Rubinius 코드는 MRI와 다른 방식으로 구성되어 있으므로 이를 위해 Github 및 '파일 찾기' 기능을 사용하고 싶습니다.
Enumerable
에 대해 자세히 알아보려면 그런 다음 'enumerable'을 입력하기만 하면 모든 관련 파일이 표시됩니다.결론
이미 보았듯이 Ruby가 많은 노력 없이 내부적으로 작업을 수행하는 방법을 배울 수 있습니다. 스스로 탐색하고 발견한 내용을 모두에게 알리세요!
이 게시물이 마음에 들면 내 뉴스레터에 가입하는 것을 잊지 말고 아래 양식에 이메일을 보내주시면 무료 업데이트 및 독점 콘텐츠를 받을 수 있습니다.