MRIソースコードの調査
しばらくRubyを使用している場合は、内部でいくつかのものがどのように機能するかについて興味があるかもしれません。
Rubyの内部を深く掘り下げる1つの方法は、Rubyを機能させるソースコードを読み取ることです。 Cを知らなくても、面白いものをいくつか拾うことができます。
ソースコードは、Rubyのgithubリポジトリにあります。
理想的には、クラス名とメソッド名を簡単に見つけることができるCodequeryのようなツールを使用する必要があります。
コアクラスの調査
ほとんどの探索はルートフォルダで行われます。ここに、Object
などのすべてのコアクラスのソースコードがあります。 object.c
内 またはArray
array.c
内 。
hash.c
を見てみましょう 。
4468行目までスクロールすると、なじみのある名前がいくつか表示されます。
これから始めましょう :
rb_cHash = rb_define_class("Hash", rb_cObject);
この行では、Hash
クラスはrb_define_class
によって定義されています 関数。 2番目の引数(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(super, klass); return klass;>
これらすべてのメソッドの定義を読むことができますが、それらはかなり自明だと思います。
st_add_direct
内 、「st」の部分は「シンボルテーブル」を意味し、これは単なるハッシュテーブルです。 rb_const_set
関数はObject
に定数を設定します クラス、これによりクラスはどこでも利用できるようになります。
そしてrb_class_inherited
inherited
を呼び出します スーパークラスのメソッドについては、このメソッドのドキュメントをここで見つけることができます。
コードの次のセクションは、メソッド定義で構成されています。 MRIはrb_define_method
を使用します それをするために。
ここに例があります :
rb_define_method(rb_cHash,"index", rb_hash_index, 1); rb_define_method(rb_cHash,"size", rb_hash_size, 0); rb_define_method(rb_cHash,"length", rb_hash_size, 0); rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);
引数は次のようになります :
- 最初の引数は、このメソッドが定義されているクラスです
- 2番目の引数はメソッド名、3番目の引数は実際にこのメソッドを実装するC関数です
- 最後の引数は、このRubyメソッドに必要な引数の数です(負の値はオプションの引数を意味します)
rb_define_singleton_method
関数はクラスメソッドを定義するために使用されます。
rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
rb_define_singleton_method
の本文 たった1行のコードです:
rb_define_method(singleton_class_of(obj), name, func, argc);
探索を続けたい場合は、object.c
を参照してください。 。
標準ライブラリの探索
わかりました。今日はこれで十分です。
Rubyコードを読んでみませんか?
Ruby標準ライブラリはRubyで記述されており、/lib
の下にあります。 ディレクトリ。
標準ライブラリには、OpenStruct、Base64
などが含まれています エンコーディングとSet
データ構造。
セットは配列に似ていますが、すべての要素が一意であるという特別なプロパティがあります。つまり、セットには重複が含まれていません。
それはどのように機能しますか?この背後にある派手なアルゴリズムはありますか?
set.rb
を見てみましょう これがHash
に裏打ちされていることがすぐにわかります オブジェクト。
# Adds the given object to the set and returns self. Use +merge+ to # add many elements at once. def add(o) @hash[o] = true self end alias << add
したがって、複製された要素を追加する場合、それがすでに存在するかどうかを確認する必要はなく、古い要素を上書きするだけです。
ルビニウスを探索する
Rubyのソースコードを調べるもう1つの方法は、Rubiniusなどの代替実装を調べることです。
RubiniusコードはMRIとは異なる方法で編成されているため、このためにGithubと「ファイルの検索」機能を使用するのが好きです。
Enumerable
について詳しく知りたい場合 次に、「enumerable」と入力するだけで、関連するすべてのファイルが表示されます。
結論
これまで見てきたように、Rubyが内部でどのように動作するかをそれほど労力をかけずに学ぶことができます。先に進んで自分で探索し、発見したことをみんなに知らせてください!
この投稿が気に入ったら、私のニュースレターに参加することを忘れないでください。下のフォームにメールをドロップするだけで、無料のアップデートと独占的なコンテンツを受け取ることができます。
-
RubyとRubyonRailsでメソッドを委任する方法
この記事は、Rubyでのメソッドの委任に関するものです。 delegateの使用方法を学習します メソッド、Forwardable モジュールとSimpleDelegator クラス。 なぜ委任が必要なのですか ? オブジェクト指向プログラミングでは、クラスが連携する方法は2つあります。 彼らは : 継承 構成 継承を使用すると、クラス階層を作成します。親クラスは、メソッド、定数、インスタンス変数の定義を、継承するクラスと共有します。 例 : Rubyでは、すべてのオブジェクトはObjectから継承します デフォルトではクラスです。 そのため、putsなどのメソッドにアクセ
-
あなたのコードはどこに行きますか?
Railsチュートリアルを終了して独自のアプリを起動すると、混乱が生じます。非CRUDの一般的なロジックはどこに行くのですか? Twitterからフォロワーを獲得することはMVCにどのように適合しますか? 2人に聞いてみると、4つの答えが得られます。または、あなたが机に頭をぶつけている間、あなたのスレッドは何時間もお互いを侮辱する賢い人々の束に発展します。いずれにせよ、あなたは頭痛の種になります。 夢見ていたアプリを作成するには、いくつかが必要です。 一般的な、Rails以外のロジック。 では、コードをどこに配置し、それでも物事をシンプルに保つのでしょうか? 簡単に始められる場所 既存のA