Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

MRI 소스 코드 탐색

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를 검색하세요. .

MRI 소스 코드 탐색

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 및 '파일 찾기' 기능을 사용하고 싶습니다.

MRI 소스 코드 탐색

Enumerable에 대해 자세히 알아보려면 그런 다음 'enumerable'을 입력하기만 하면 모든 관련 파일이 표시됩니다.

결론

이미 보았듯이 Ruby가 많은 노력 없이 내부적으로 작업을 수행하는 방법을 배울 수 있습니다. 스스로 탐색하고 발견한 내용을 모두에게 알리세요!

이 게시물이 마음에 들면 내 뉴스레터에 가입하는 것을 잊지 말고 아래 양식에 이메일을 보내주시면 무료 업데이트 및 독점 콘텐츠를 받을 수 있습니다.