SlideShare a Scribd company logo
1 of 22
Ruby のコードを読んでみよう
       ( 入門編 )
まずは DOWNLOAD
今回は ruby2.0... ではなくて、 ruby-1.9.3-p374
で解説します
環境は mac でまずはソースコードをダウン
ロード
http://www.ruby-lang.org/ja/downloads/

Tar ボールを展開したら普通に


./configure
でビルドできます
make                        (※gcc 必須 )
解凍してみる


array.c      dmyversion.c     inits.c    parse.c       ruby.c          variable.c

bignum.c      encoding.c       io.c        prelude.c     safe.c        version.c

class.c     enum.c           iseq.c      proc.c        signal.c       vm.c

compar.c      enumerator.c     lex.c       process.c    sprintf.c     vm_dump.c

compile.c    error.c         load.c      random.c        st.c          vm_eval.c

complex.c    eval.c          main.c        range.c       strftime.c    vm_exec.c

cont.c       eval_error.c    marshal.c    rational.c   string.c       vm_insnhelper.c

debug.c      eval_jump.c       math.c       re.c          struct.c      vm_method.c

......
なんか色々ファイルあったけど
「 array.c 」とか「 string.c 」とかあるから
          多分 C 言語だよねっ!
とりあえず「 array.c 」を開いてみよう
とりあえず Array.c の内側
 とりあえず上からそれっぽい関数名を拾っていくと
 なんだか”動きの予想できそう”な関数がたくさんある

static VALUE ary_new(VALUE klass, long capa)

static VALUE rb_ary_push_m(int argc, VALUE *argv, VALUE ary)

VALUE rb_ary_pop(VALUE ary)
とりあえず Array#push を
 今回のテーマにします
Array#push の内容
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
   rb_ary_modify(ary);
   return rb_ary_push_1(ary, item);
}

static VALUE
rb_ary_push_1(VALUE ary, VALUE item)
{
     long idx = RARRAY_LEN(ary);

    if (idx >= ARY_CAPA(ary)) {
        ary_double_capa(ary, idx);
    }
    RARRAY_PTR(ary)[idx] = item;
    ARY_SET_LEN(ary, idx + 1);
    return ary;
}
Array#push の内容
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
   rb_ary_modify(ary);
   return rb_ary_push_1(ary, item);
}

static VALUE
rb_ary_push_1(VALUE ary, VALUE item)
{
     long idx = RARRAY_LEN(ary); // 長さを調べる

    if (idx >= ARY_CAPA(ary)) {
        ary_double_capa(ary, idx);
    }
    RARRAY_PTR(ary)[idx] = item;
    ARY_SET_LEN(ary, idx + 1);
    return ary;
}
Array#push の内容
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
   rb_ary_modify(ary);
   return rb_ary_push_1(ary, item);
}

static VALUE
rb_ary_push_1(VALUE ary, VALUE item)
{
     long idx = RARRAY_LEN(ary); // 長さを調べる

    if (idx >= ARY_CAPA(ary)) {
        ary_double_capa(ary, idx);
    }
    RARRAY_PTR(ary)[idx] = item;
    ARY_SET_LEN(ary, idx + 1);
    return ary;
}
Array#push の内容
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
   rb_ary_modify(ary);
   return rb_ary_push_1(ary, item);
}

static VALUE
rb_ary_push_1(VALUE ary, VALUE item)
{
     long idx = RARRAY_LEN(ary);

    if (idx >= ARY_CAPA(ary)) { // 長さが足りないときは
        ary_double_capa(ary, idx); // 拡張
    }
    RARRAY_PTR(ary)[idx] = item;
    ARY_SET_LEN(ary, idx + 1);
    return ary;
}
Array#push の内容
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
   rb_ary_modify(ary);
   return rb_ary_push_1(ary, item);
}

static VALUE
rb_ary_push_1(VALUE ary, VALUE item)
{
     long idx = RARRAY_LEN(ary);

    if (idx >= ARY_CAPA(ary)) {
        ary_double_capa(ary, idx);
    }
    RARRAY_PTR(ary)[idx] = item; // 配列の要素をセット
    ARY_SET_LEN(ary, idx + 1);
    return ary;
}
… 読めるぞ!私にもコードが読めるッ!!
メソッドの対応付けの箇所


ファイル末尾の void Init_Array(void) 関数を参
照してみると
実際の method をココで紐付けている
rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
読めるので実際に書き換えてみる




object.c の nil_inspect という関数を書き換える
    ( どう見ても Object#inspect メソッド )
書き換え (object.c)
998 static VALUE
999 nil_inspect(VALUE obj)
1000 {
1001 return rb_usascii_str_new2("nil");
1002 }
書き換え
998 static VALUE
999 nil_inspect(VALUE obj)
1000 {
1001 return rb_usascii_str_new2("hogeobj");
1002 }




             ( 表示を hogeobj に変更 )
実行してみる
make
./ruby -e ' p nil.inspect '


コンソールに "hogeobj" が表示される
今回は、 aray.c と object.c の内側を
   ちょっと覗きましたが
実は、 ruby 組み込みの60クラスのうち、29クラスは
同じファイル名を ruby のコード中に持っていたりする

object ARGF                 module Errno             module Marshal           module Process::UID

class Array                 class FalseClass         class MatchData          class Random

class BasicObject           class Fiber              module Math              class Range

class Bignum                class File               class Method             class Rational

class Binding               module File::Constants   class Module             class Regexp

class Class                 class File::Stat         class Mutex              module Signal

module Comparable           module FileTest          class NilClass           class String

class Complex               class Fixnum             class Numeric            class Struct

class Data                  class Float              class Object             class Struct::Tms

class Dir                   module GC                module ObjectSpace       class Symbol

object ENV                  module GC::Profiler      class Proc               class Thread

class Encoding              class Hash               module Process           class ThreadGroup

class Encoding::Converter   class IO                 module Process::GID      class Time

module Enumerable           class Integer            module Process::Status   class TrueClass

class Enumerator            module Kernel            module Process::Sys      class UnboundMethod
まとめ
ruby は C 言語、しかも教科書的実装で
とっても読みやすい♪

More Related Content

What's hot

Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelereaseShiqiao Du
 
Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Kazuki Ohta
 
Kyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseKyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseMikio Hirabayashi
 
Jvm reading-synchronization
Jvm reading-synchronizationJvm reading-synchronization
Jvm reading-synchronizationMinoru Nakamura
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweightgintenlabo
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナドKousuke Ruichi
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.specKent Ohashi
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cythonfuzzysphere
 
Cython ことはじめ
Cython ことはじめCython ことはじめ
Cython ことはじめgion_XY
 
データサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるデータサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるShintaro Fukushima
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPyShiqiao Du
 
はてなブックマーク in Scala
はてなブックマーク in Scalaはてなブックマーク in Scala
はてなブックマーク in ScalaLintaro Ina
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたってTsuyoshi Matsudate
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたってTsuyoshi Matsudate
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageTaku Miyakawa
 

What's hot (17)

Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方
 
Kyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseKyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in Japanese
 
Jvm reading-synchronization
Jvm reading-synchronizationJvm reading-synchronization
Jvm reading-synchronization
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweight
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナド
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.spec
 
JVM-Reading-ParalleGC
JVM-Reading-ParalleGCJVM-Reading-ParalleGC
JVM-Reading-ParalleGC
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cython
 
Cython ことはじめ
Cython ことはじめCython ことはじめ
Cython ことはじめ
 
データサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるデータサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみる
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
 
はてなブックマーク in Scala
はてなブックマーク in Scalaはてなブックマーク in Scala
はてなブックマーク in Scala
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
 

Similar to Rubyのソースコードを読んでみよう(入門編)

ソースコードリーディングの基礎
ソースコードリーディングの基礎ソースコードリーディングの基礎
ソースコードリーディングの基礎hogemuta
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックスTomoharu ASAMI
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsShogo Sensui
 
Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by HapyrusKoichi Fujikawa
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
メタメタプログラミングRuby
メタメタプログラミングRubyメタメタプログラミングRuby
メタメタプログラミングRubyemasaka
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行guest5f4320
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタートShumpei Shiraishi
 
クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術Koichi Fujikawa
 
Rails3.1rc4を試してみた
Rails3.1rc4を試してみたRails3.1rc4を試してみた
Rails3.1rc4を試してみたTakahiro Hidaka
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめMikiya Okuno
 
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜Naohiro Yoshida
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングkunihikokaneko1
 
Springでdao 20070413
Springでdao 20070413Springでdao 20070413
Springでdao 20070413Funato Takashi
 

Similar to Rubyのソースコードを読んでみよう(入門編) (20)

ソースコードリーディングの基礎
ソースコードリーディングの基礎ソースコードリーディングの基礎
ソースコードリーディングの基礎
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
Project lambda
Project lambdaProject lambda
Project lambda
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.js
 
Rpscala2011 0601
Rpscala2011 0601Rpscala2011 0601
Rpscala2011 0601
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by Hapyrus
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
メタメタプログラミングRuby
メタメタプログラミングRubyメタメタプログラミングRuby
メタメタプログラミングRuby
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 
クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術
 
Rails3.1rc4を試してみた
Rails3.1rc4を試してみたRails3.1rc4を試してみた
Rails3.1rc4を試してみた
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめ
 
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
 
Springでdao 20070413
Springでdao 20070413Springでdao 20070413
Springでdao 20070413
 

More from baban ba-n

Typusとadministrateを比較してみよう
Typusとadministrateを比較してみようTypusとadministrateを比較してみよう
Typusとadministrateを比較してみようbaban ba-n
 
Typusと付き合ってきた話
Typusと付き合ってきた話Typusと付き合ってきた話
Typusと付き合ってきた話baban ba-n
 
ハッカソン。来た、見た、負けた! Spajam2016仙台予選
ハッカソン。来た、見た、負けた! Spajam2016仙台予選ハッカソン。来た、見た、負けた! Spajam2016仙台予選
ハッカソン。来た、見た、負けた! Spajam2016仙台予選baban ba-n
 
ガラホ、なるものに対応してきた
ガラホ、なるものに対応してきたガラホ、なるものに対応してきた
ガラホ、なるものに対応してきたbaban ba-n
 
Minitest調べてみた
Minitest調べてみたMinitest調べてみた
Minitest調べてみたbaban ba-n
 
人工言語ロジバン超入門編
人工言語ロジバン超入門編人工言語ロジバン超入門編
人工言語ロジバン超入門編baban ba-n
 
普通のエンジニアが【ロジバン】やってみた
普通のエンジニアが【ロジバン】やってみた普通のエンジニアが【ロジバン】やってみた
普通のエンジニアが【ロジバン】やってみたbaban ba-n
 
プログラミング言語Cyanの紹介
プログラミング言語Cyanの紹介プログラミング言語Cyanの紹介
プログラミング言語Cyanの紹介baban ba-n
 
Rubyのコードを読んでみよう(オブジェクト編)
Rubyのコードを読んでみよう(オブジェクト編)Rubyのコードを読んでみよう(オブジェクト編)
Rubyのコードを読んでみよう(オブジェクト編)baban ba-n
 
rails 管理画面作成gem Typus解説
rails 管理画面作成gem Typus解説rails 管理画面作成gem Typus解説
rails 管理画面作成gem Typus解説baban ba-n
 
名前重要 超重要
名前重要 超重要名前重要 超重要
名前重要 超重要baban ba-n
 
Rails-Plugin Flexturesの紹介
Rails-Plugin Flexturesの紹介Rails-Plugin Flexturesの紹介
Rails-Plugin Flexturesの紹介baban ba-n
 

More from baban ba-n (12)

Typusとadministrateを比較してみよう
Typusとadministrateを比較してみようTypusとadministrateを比較してみよう
Typusとadministrateを比較してみよう
 
Typusと付き合ってきた話
Typusと付き合ってきた話Typusと付き合ってきた話
Typusと付き合ってきた話
 
ハッカソン。来た、見た、負けた! Spajam2016仙台予選
ハッカソン。来た、見た、負けた! Spajam2016仙台予選ハッカソン。来た、見た、負けた! Spajam2016仙台予選
ハッカソン。来た、見た、負けた! Spajam2016仙台予選
 
ガラホ、なるものに対応してきた
ガラホ、なるものに対応してきたガラホ、なるものに対応してきた
ガラホ、なるものに対応してきた
 
Minitest調べてみた
Minitest調べてみたMinitest調べてみた
Minitest調べてみた
 
人工言語ロジバン超入門編
人工言語ロジバン超入門編人工言語ロジバン超入門編
人工言語ロジバン超入門編
 
普通のエンジニアが【ロジバン】やってみた
普通のエンジニアが【ロジバン】やってみた普通のエンジニアが【ロジバン】やってみた
普通のエンジニアが【ロジバン】やってみた
 
プログラミング言語Cyanの紹介
プログラミング言語Cyanの紹介プログラミング言語Cyanの紹介
プログラミング言語Cyanの紹介
 
Rubyのコードを読んでみよう(オブジェクト編)
Rubyのコードを読んでみよう(オブジェクト編)Rubyのコードを読んでみよう(オブジェクト編)
Rubyのコードを読んでみよう(オブジェクト編)
 
rails 管理画面作成gem Typus解説
rails 管理画面作成gem Typus解説rails 管理画面作成gem Typus解説
rails 管理画面作成gem Typus解説
 
名前重要 超重要
名前重要 超重要名前重要 超重要
名前重要 超重要
 
Rails-Plugin Flexturesの紹介
Rails-Plugin Flexturesの紹介Rails-Plugin Flexturesの紹介
Rails-Plugin Flexturesの紹介
 

Rubyのソースコードを読んでみよう(入門編)

  • 2. まずは DOWNLOAD 今回は ruby2.0... ではなくて、 ruby-1.9.3-p374 で解説します 環境は mac でまずはソースコードをダウン ロード http://www.ruby-lang.org/ja/downloads/ Tar ボールを展開したら普通に ./configure でビルドできます make (※gcc 必須 )
  • 3. 解凍してみる array.c dmyversion.c inits.c parse.c ruby.c variable.c bignum.c encoding.c io.c prelude.c safe.c version.c class.c enum.c iseq.c proc.c signal.c vm.c compar.c enumerator.c lex.c process.c sprintf.c vm_dump.c compile.c error.c load.c random.c st.c vm_eval.c complex.c eval.c main.c range.c strftime.c vm_exec.c cont.c eval_error.c marshal.c rational.c string.c vm_insnhelper.c debug.c eval_jump.c math.c re.c struct.c vm_method.c ......
  • 5. 「 array.c 」とか「 string.c 」とかあるから 多分 C 言語だよねっ!
  • 7. とりあえず Array.c の内側 とりあえず上からそれっぽい関数名を拾っていくと なんだか”動きの予想できそう”な関数がたくさんある static VALUE ary_new(VALUE klass, long capa) static VALUE rb_ary_push_m(int argc, VALUE *argv, VALUE ary) VALUE rb_ary_pop(VALUE ary)
  • 8. とりあえず Array#push を 今回のテーマにします
  • 9. Array#push の内容 VALUE rb_ary_push(VALUE ary, VALUE item) { rb_ary_modify(ary); return rb_ary_push_1(ary, item); } static VALUE rb_ary_push_1(VALUE ary, VALUE item) { long idx = RARRAY_LEN(ary); if (idx >= ARY_CAPA(ary)) { ary_double_capa(ary, idx); } RARRAY_PTR(ary)[idx] = item; ARY_SET_LEN(ary, idx + 1); return ary; }
  • 10. Array#push の内容 VALUE rb_ary_push(VALUE ary, VALUE item) { rb_ary_modify(ary); return rb_ary_push_1(ary, item); } static VALUE rb_ary_push_1(VALUE ary, VALUE item) { long idx = RARRAY_LEN(ary); // 長さを調べる if (idx >= ARY_CAPA(ary)) { ary_double_capa(ary, idx); } RARRAY_PTR(ary)[idx] = item; ARY_SET_LEN(ary, idx + 1); return ary; }
  • 11. Array#push の内容 VALUE rb_ary_push(VALUE ary, VALUE item) { rb_ary_modify(ary); return rb_ary_push_1(ary, item); } static VALUE rb_ary_push_1(VALUE ary, VALUE item) { long idx = RARRAY_LEN(ary); // 長さを調べる if (idx >= ARY_CAPA(ary)) { ary_double_capa(ary, idx); } RARRAY_PTR(ary)[idx] = item; ARY_SET_LEN(ary, idx + 1); return ary; }
  • 12. Array#push の内容 VALUE rb_ary_push(VALUE ary, VALUE item) { rb_ary_modify(ary); return rb_ary_push_1(ary, item); } static VALUE rb_ary_push_1(VALUE ary, VALUE item) { long idx = RARRAY_LEN(ary); if (idx >= ARY_CAPA(ary)) { // 長さが足りないときは ary_double_capa(ary, idx); // 拡張 } RARRAY_PTR(ary)[idx] = item; ARY_SET_LEN(ary, idx + 1); return ary; }
  • 13. Array#push の内容 VALUE rb_ary_push(VALUE ary, VALUE item) { rb_ary_modify(ary); return rb_ary_push_1(ary, item); } static VALUE rb_ary_push_1(VALUE ary, VALUE item) { long idx = RARRAY_LEN(ary); if (idx >= ARY_CAPA(ary)) { ary_double_capa(ary, idx); } RARRAY_PTR(ary)[idx] = item; // 配列の要素をセット ARY_SET_LEN(ary, idx + 1); return ary; }
  • 15. メソッドの対応付けの箇所 ファイル末尾の void Init_Array(void) 関数を参 照してみると 実際の method をココで紐付けている rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1); rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0); rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
  • 16. 読めるので実際に書き換えてみる object.c の nil_inspect という関数を書き換える ( どう見ても Object#inspect メソッド )
  • 17. 書き換え (object.c) 998 static VALUE 999 nil_inspect(VALUE obj) 1000 { 1001 return rb_usascii_str_new2("nil"); 1002 }
  • 18. 書き換え 998 static VALUE 999 nil_inspect(VALUE obj) 1000 { 1001 return rb_usascii_str_new2("hogeobj"); 1002 } ( 表示を hogeobj に変更 )
  • 19. 実行してみる make ./ruby -e ' p nil.inspect ' コンソールに "hogeobj" が表示される
  • 20. 今回は、 aray.c と object.c の内側を ちょっと覗きましたが
  • 21. 実は、 ruby 組み込みの60クラスのうち、29クラスは 同じファイル名を ruby のコード中に持っていたりする object ARGF module Errno module Marshal module Process::UID class Array class FalseClass class MatchData class Random class BasicObject class Fiber module Math class Range class Bignum class File class Method class Rational class Binding module File::Constants class Module class Regexp class Class class File::Stat class Mutex module Signal module Comparable module FileTest class NilClass class String class Complex class Fixnum class Numeric class Struct class Data class Float class Object class Struct::Tms class Dir module GC module ObjectSpace class Symbol object ENV module GC::Profiler class Proc class Thread class Encoding class Hash module Process class ThreadGroup class Encoding::Converter class IO module Process::GID class Time module Enumerable class Integer module Process::Status class TrueClass class Enumerator module Kernel module Process::Sys class UnboundMethod
  • 22. まとめ ruby は C 言語、しかも教科書的実装で とっても読みやすい♪