Ruby 拡張モジュール入門

Kenta Murata
Kenta MurataCRO at Xica Co., Ltd.
Ruby
             Ruby
             拡張モジュール⼊⾨
             拡張モジュール⼊⾨
             むらけん




2007-11-17
おしながき
             おしながき
   拡張モジュールとは
   なにもしない拡張モジュール
   hello.so
   拡張モジュールを作る前に
   まとめ



2007-11-17      Ruby 勉強会@札幌 #6   1
拡張モジュールとは
             拡張モジュールとは
               ⽇本語でおk


                                2



2007-11-17     Ruby 勉強会@札幌 #6
拡張モジュールって何?
             拡張モジュールって何?
拡張モジュールとは・・・
        Ruby では実現不可能だけど,C ⾔語なら実現可
        能な事柄を,C ⾔語で実装して Ruby から使えるよ
        うにするための共有ライブラリ
        Ruby で実装すると遅いけど,C ⾔語なら実⽤的な
        実⾏速度を実現できるようなアルゴリズムなどを,C
        ⾔語で実装して Ruby から使えるようにするための
        共有ライブラリ
             アセンブリ⾔語も使えるよ\(^o^)/
2007-11-17           Ruby 勉強会@札幌 #6   3
拡張モジュールの例
             拡張モジュールの例
   標準添付                            独⽴配布
        Ruby/OpenSSL                     Ruby/GNOME2
        Ruby/Win32API                    RubyCocoa
        Enumerator                       Libxml-Ruby
        iconv                            Ruby PostgreSQL
        Ruby/Tk                          MySQL/Ruby
        Win32OLE                         fastthread
        Ruby/Zlib                        http11 (mongrel)


2007-11-17              Ruby 勉強会@札幌 #6                      4
なにもしない
              なにもしない
             拡張モジュール
             拡張モジュール
             nothing to do


                                5



2007-11-17     Ruby 勉強会@札幌 #6
準   備
             準   備
 3つのファイルを nothing ディレクトリの中に⼊れましょう

 [nothing.c]                [extconf.rb]
 void                       require 'mkmf'
 Init_nothing(void)
 {                          create_makefile('nothing')
 }
                            ~/nothing$ ls
 [depends]                  depends extconf.rb nothing.c
 nothing.o: nothing.c       ~/nothing$

2007-11-17              Ruby 勉強会@札幌 #6                     6
コンパイル
             コンパイル
 extconf.rb を実⾏することによって Makefile が作られます.
 作成された Makefile を make することでコンパイルします.
 make の後に⽣成される nothing.so が拡張モジュールです.

 ~/nothing$ ruby extconf.rb
 creating Makefile
 ~/nothing$ ls
 Makefile depends extconf.rb                nothing.c
 ~/nothing$ make
 cc -I. -I/usr/lib/ruby/1.8/i486-linux -I/usr/lib/ruby/1.8/i486-linux -I. -fPIC -fno-stric...
 cc -shared -o nothing.so nothing.o -Lquot;.quot; -Lquot;/usr/libquot; -L. -rdynamic -Wl,-export-dynamic ...
 ~/nothing$ ls
 Makefile depends          extconf.rb       nothing.c nothing.o            nothing.so

2007-11-17                          Ruby 勉強会@札幌 #6                                              7
使ってみる
             使ってみる
 出来上がった nothing.so を Ruby から使うには
 require 'nothing' を⾏います.

 ~/nothing$ irb
 irb(main):001:0> require 'nothing'
 => true
 irb(main):002:0> exit
 ~/nothing$




2007-11-17                Ruby 勉強会@札幌 #6   8
ここまでのまとめ (1)
             ここまでのまとめ (1)
   拡張モジュールに必ず必要な関数
        void Init_モジュール名(void) { ... }
        拡張モジュールがロードされた直後に Ruby インタ
        プリタがこの関数を呼び出す
         本来ならば,この関数の中で拡張モジュールの初
        期化処理が⾏われる




2007-11-17        Ruby 勉強会@札幌 #6         9
ここまでのまとめ (2)
              ここまでのまとめ (2)
   Ruby に標準添付されている拡張モジュール
   開発環境
        extconf.rb の中で mkmf ライブラリを⽤いて,
        Makefile を作成するための処理を⾏う
             • とりあえず
                  create_makefile('モジュール名')
               と書くことで「モジュール名.so」を⽣成するための
               Makefile が作られる
        depends ファイルの中に Makefile に書いて欲し
        い依存関係を記述する
2007-11-17              Ruby 勉強会@札幌 #6        10
hello.so
             hello.so
             そう,こんにちわ


                               11



2007-11-17    Ruby 勉強会@札幌 #6
hello.c
              hello.c
 [hello.c]                                 [左から続き]
 #include <ruby.h>                         void
 #include <stdio.h>                        Init_hello(void)
                                           {
 static VALUE                                VALUE cHello;
 hello_hello(VALUE self)
 {                                             printf(quot;[XXX] Init_hello¥nquot;);
   VALUE str;
                                               cHello = rb_define_class(
     printf(quot;[XXX] hello_hello¥nquot;);                       quot;Helloquot;, rb_cObject);
                                               rb_define_method(
     str = rb_str_new2(quot;hello, worldquot;);          cHello, quot;helloquot;, hello_hello, 0);
     rb_io_puts(1, &str, rb_stdout);       }

     return self;
 }


2007-11-17                        Ruby 勉強会@札幌 #6                                     12
コンパイル
             コンパイル
 [extconf.rb]                            ~/hello$   ls
 require 'mkmf'                          depends    extconf.rb hello.c
                                         ~/hello$   ruby extconf.rb
 create_makefile('hello')                creating   Makefile
                                         ~/hello$   make
                                         cc -I. -I/usr/lib/ruby/1.8/i486-linux -
                                         I/usr/lib/ruby/1.8/i486-linux -I. -fPIC -
                                         fno-strict-aliasing -g -O2 -fPIC -c
 [depends]
                                         hello.c
 hello.o: hello.c $(hdrdir)/ruby.h
                                         cc -shared -o hello.so hello.o -Lquot;.quot; -
                                         Lquot;/usr/libquot; -L. -rdynamic -Wl,-export-
                                         dynamic    -lruby1.8 -lpthread -ldl -
                                         lcrypt -lm   -lc
                                         ~/hello$ ls
                                         depends extconf.rb hello.c hello.o
                                         hello.so



2007-11-17                      Ruby 勉強会@札幌 #6                                       13
使ってみる
             使ってみる
 ~/hello$ irb                            void
 irb(main):001:0> require 'hello'        Init_hello(void)
 [XXX] Init_hello                        {
 => true                                   VALUE cHello;
 irb(main):002:0> h = Hello.new
 => #<Hello:0xb7c7e590>                    printf(quot;[XXX] Init_hello¥nquot;);
 irb(main):003:0> h.hello                ======================================
 [XXX] hello_hello                       static VALUE
 hello, world                            hello_hello(VALUE self)
 => #<Hello:0xb7c7e590>                  {
 irb(main):004:0> exit                     VALUE str;
 ~/hello$
                                           printf(quot;[XXX] hello_hello¥nquot;);
                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                           return self;
                                         }


2007-11-17                      Ruby 勉強会@札幌 #6                                14
ここまでのまとめ (1)
             ここまでのまとめ (1)
   クラスを定義する
        rb_define_class(クラス名, 親クラスオブジェクト)
   クラスにインスタンスメソッドを定義する
        rb_define_method(
             クラスオブジェクト,
             メソッド名,
             メソッドを実装している関数,
             引数の個数)

2007-11-17         Ruby 勉強会@札幌 #6       15
ここまでのまとめ (2)
               ここまでのまとめ (2)
   メソッドの実体となる関数 (hello_hello)
        第1仮引数・・・レシーバオブジェクト
        その他・・・メソッドの引数

   Ruby の⽂字列オブジェクトを⽣成する
        rb_str_new2(C の⽂字列)

   puts
        rb_io_puts(1, &⽂字列, rb_stdout)
             • 本当は rb_io_puts(argc, argv, rb_stdout) で,argv が puts
               に渡す実引数の C 配列,argc がその⻑さ

2007-11-17                    Ruby 勉強会@札幌 #6                         16
拡張モジュールを
             拡張モジュールを
               作る前に
               作る前に
             そんなに難しくないよ


                                17



2007-11-17     Ruby 勉強会@札幌 #6
おちついて⼀読すべし
             おちついて⼀読すべし
   Ruby には拡張モジュールの作り⽅のドキュメ
   ントがもれなくついてくる!
        README.EXT
        README.EXT.ja




2007-11-17          Ruby 勉強会@札幌 #6   18
拡張モジュールを作るとは
             拡張モジュールを作るとは
             どういうことか?
             どういうことか?

     Ruby インタプリタが理解できることば
        構⽂⽊
        C ⾔語


   拡張モジュールを作る
       = Ruby インタプリタとお喋りする


2007-11-17       Ruby 勉強会@札幌 #6   19
参考になるものたち
             参考になるものたち
     Ruby のソースを読むべし!
        array.c
        hash.c
        object.c
        string.c

   よく使うクラスを実装しているコードを読むことで
   拡張モジュール作成のための知識を増やそう

2007-11-17         Ruby 勉強会@札幌 #6   20
まとめ
              まとめ
             MA☆TO☆めけーも


                                21



2007-11-17     Ruby 勉強会@札幌 #6
拡張モジュールを作ろう!

             C ⾔語で Ruby とお喋りしよう




2007-11-17         Ruby 勉強会@札幌 #6   22
1 of 23

Recommended

Web scale backups for MySQL, Алексей Копытов (Percona) by
Web scale backups for MySQL, Алексей Копытов (Percona)Web scale backups for MySQL, Алексей Копытов (Percona)
Web scale backups for MySQL, Алексей Копытов (Percona)Ontico
1.3K views33 slides
Float is Legacy by
Float is LegacyFloat is Legacy
Float is LegacyKenta Murata
3.8K views79 slides
校内勉強会のススメ An encouragement to hold workshops In your school by
校内勉強会のススメ An encouragement to hold workshops In your school校内勉強会のススメ An encouragement to hold workshops In your school
校内勉強会のススメ An encouragement to hold workshops In your schoolKenta Murata
1.6K views50 slides
5分弱で分かる量子ビット by
5分弱で分かる量子ビット5分弱で分かる量子ビット
5分弱で分かる量子ビットKenta Murata
6.7K views32 slides
Introduction to ATDD with Cucumber and RSpec by
Introduction to ATDD with Cucumber and RSpecIntroduction to ATDD with Cucumber and RSpec
Introduction to ATDD with Cucumber and RSpecKenta Murata
14.1K views48 slides
The world without the literal notation for floating-point numbers by
The world without the literal notation for floating-point numbersThe world without the literal notation for floating-point numbers
The world without the literal notation for floating-point numbersKenta Murata
1.2K views38 slides

More Related Content

More from Kenta Murata

関数型プログラミングの世界 by
関数型プログラミングの世界関数型プログラミングの世界
関数型プログラミングの世界Kenta Murata
3.7K views64 slides
Let's begin Behavior Driven Development using RSpec by
Let's begin Behavior Driven Development using RSpecLet's begin Behavior Driven Development using RSpec
Let's begin Behavior Driven Development using RSpecKenta Murata
1.6K views87 slides
Rubyをたのしくするために私が考えていること by
Rubyをたのしくするために私が考えていることRubyをたのしくするために私が考えていること
Rubyをたのしくするために私が考えていることKenta Murata
1.9K views97 slides
Ruby の懸案事項 by
Ruby の懸案事項Ruby の懸案事項
Ruby の懸案事項Kenta Murata
2.6K views38 slides
Rubykaigi2010mrkn bigdecimal by
Rubykaigi2010mrkn bigdecimalRubykaigi2010mrkn bigdecimal
Rubykaigi2010mrkn bigdecimalKenta Murata
1K views52 slides
Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案) by
Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案)Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案)
Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案)Kenta Murata
801 views1 slide

More from Kenta Murata(12)

関数型プログラミングの世界 by Kenta Murata
関数型プログラミングの世界関数型プログラミングの世界
関数型プログラミングの世界
Kenta Murata3.7K views
Let's begin Behavior Driven Development using RSpec by Kenta Murata
Let's begin Behavior Driven Development using RSpecLet's begin Behavior Driven Development using RSpec
Let's begin Behavior Driven Development using RSpec
Kenta Murata1.6K views
Rubyをたのしくするために私が考えていること by Kenta Murata
Rubyをたのしくするために私が考えていることRubyをたのしくするために私が考えていること
Rubyをたのしくするために私が考えていること
Kenta Murata1.9K views
Ruby の懸案事項 by Kenta Murata
Ruby の懸案事項Ruby の懸案事項
Ruby の懸案事項
Kenta Murata2.6K views
Rubykaigi2010mrkn bigdecimal by Kenta Murata
Rubykaigi2010mrkn bigdecimalRubykaigi2010mrkn bigdecimal
Rubykaigi2010mrkn bigdecimal
Kenta Murata1K views
Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案) by Kenta Murata
Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案)Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案)
Ruby における絵文字エンコーディング間の相互変換ダイアグラム (案)
Kenta Murata801 views
Ruby の標準乱数生成器とその改善案 by Kenta Murata
Ruby の標準乱数生成器とその改善案Ruby の標準乱数生成器とその改善案
Ruby の標準乱数生成器とその改善案
Kenta Murata4K views
5分で分かる Measure by Kenta Murata
5分で分かる Measure5分で分かる Measure
5分で分かる Measure
Kenta Murata1.9K views
Measure 単位付き数値ライブラリ by Kenta Murata
Measure 単位付き数値ライブラリMeasure 単位付き数値ライブラリ
Measure 単位付き数値ライブラリ
Kenta Murata1.5K views
北海道関数型言語勉強会@札幌#2のお知らせ by Kenta Murata
北海道関数型言語勉強会@札幌#2のお知らせ北海道関数型言語勉強会@札幌#2のお知らせ
北海道関数型言語勉強会@札幌#2のお知らせ
Kenta Murata770 views

Ruby 拡張モジュール入門

  • 1. Ruby Ruby 拡張モジュール⼊⾨ 拡張モジュール⼊⾨ むらけん 2007-11-17
  • 2. おしながき おしながき 拡張モジュールとは なにもしない拡張モジュール hello.so 拡張モジュールを作る前に まとめ 2007-11-17 Ruby 勉強会@札幌 #6 1
  • 3. 拡張モジュールとは 拡張モジュールとは ⽇本語でおk 2 2007-11-17 Ruby 勉強会@札幌 #6
  • 4. 拡張モジュールって何? 拡張モジュールって何? 拡張モジュールとは・・・ Ruby では実現不可能だけど,C ⾔語なら実現可 能な事柄を,C ⾔語で実装して Ruby から使えるよ うにするための共有ライブラリ Ruby で実装すると遅いけど,C ⾔語なら実⽤的な 実⾏速度を実現できるようなアルゴリズムなどを,C ⾔語で実装して Ruby から使えるようにするための 共有ライブラリ アセンブリ⾔語も使えるよ\(^o^)/ 2007-11-17 Ruby 勉強会@札幌 #6 3
  • 5. 拡張モジュールの例 拡張モジュールの例 標準添付 独⽴配布 Ruby/OpenSSL Ruby/GNOME2 Ruby/Win32API RubyCocoa Enumerator Libxml-Ruby iconv Ruby PostgreSQL Ruby/Tk MySQL/Ruby Win32OLE fastthread Ruby/Zlib http11 (mongrel) 2007-11-17 Ruby 勉強会@札幌 #6 4
  • 6. なにもしない なにもしない 拡張モジュール 拡張モジュール nothing to do 5 2007-11-17 Ruby 勉強会@札幌 #6
  • 7. 備 準 備 3つのファイルを nothing ディレクトリの中に⼊れましょう [nothing.c] [extconf.rb] void require 'mkmf' Init_nothing(void) { create_makefile('nothing') } ~/nothing$ ls [depends] depends extconf.rb nothing.c nothing.o: nothing.c ~/nothing$ 2007-11-17 Ruby 勉強会@札幌 #6 6
  • 8. コンパイル コンパイル extconf.rb を実⾏することによって Makefile が作られます. 作成された Makefile を make することでコンパイルします. make の後に⽣成される nothing.so が拡張モジュールです. ~/nothing$ ruby extconf.rb creating Makefile ~/nothing$ ls Makefile depends extconf.rb nothing.c ~/nothing$ make cc -I. -I/usr/lib/ruby/1.8/i486-linux -I/usr/lib/ruby/1.8/i486-linux -I. -fPIC -fno-stric... cc -shared -o nothing.so nothing.o -Lquot;.quot; -Lquot;/usr/libquot; -L. -rdynamic -Wl,-export-dynamic ... ~/nothing$ ls Makefile depends extconf.rb nothing.c nothing.o nothing.so 2007-11-17 Ruby 勉強会@札幌 #6 7
  • 9. 使ってみる 使ってみる 出来上がった nothing.so を Ruby から使うには require 'nothing' を⾏います. ~/nothing$ irb irb(main):001:0> require 'nothing' => true irb(main):002:0> exit ~/nothing$ 2007-11-17 Ruby 勉強会@札幌 #6 8
  • 10. ここまでのまとめ (1) ここまでのまとめ (1) 拡張モジュールに必ず必要な関数 void Init_モジュール名(void) { ... } 拡張モジュールがロードされた直後に Ruby インタ プリタがこの関数を呼び出す 本来ならば,この関数の中で拡張モジュールの初 期化処理が⾏われる 2007-11-17 Ruby 勉強会@札幌 #6 9
  • 11. ここまでのまとめ (2) ここまでのまとめ (2) Ruby に標準添付されている拡張モジュール 開発環境 extconf.rb の中で mkmf ライブラリを⽤いて, Makefile を作成するための処理を⾏う • とりあえず create_makefile('モジュール名') と書くことで「モジュール名.so」を⽣成するための Makefile が作られる depends ファイルの中に Makefile に書いて欲し い依存関係を記述する 2007-11-17 Ruby 勉強会@札幌 #6 10
  • 12. hello.so hello.so そう,こんにちわ 11 2007-11-17 Ruby 勉強会@札幌 #6
  • 13. hello.c hello.c [hello.c] [左から続き] #include <ruby.h> void #include <stdio.h> Init_hello(void) { static VALUE VALUE cHello; hello_hello(VALUE self) { printf(quot;[XXX] Init_hello¥nquot;); VALUE str; cHello = rb_define_class( printf(quot;[XXX] hello_hello¥nquot;); quot;Helloquot;, rb_cObject); rb_define_method( str = rb_str_new2(quot;hello, worldquot;); cHello, quot;helloquot;, hello_hello, 0); rb_io_puts(1, &str, rb_stdout); } return self; } 2007-11-17 Ruby 勉強会@札幌 #6 12
  • 14. コンパイル コンパイル [extconf.rb] ~/hello$ ls require 'mkmf' depends extconf.rb hello.c ~/hello$ ruby extconf.rb create_makefile('hello') creating Makefile ~/hello$ make cc -I. -I/usr/lib/ruby/1.8/i486-linux - I/usr/lib/ruby/1.8/i486-linux -I. -fPIC - fno-strict-aliasing -g -O2 -fPIC -c [depends] hello.c hello.o: hello.c $(hdrdir)/ruby.h cc -shared -o hello.so hello.o -Lquot;.quot; - Lquot;/usr/libquot; -L. -rdynamic -Wl,-export- dynamic -lruby1.8 -lpthread -ldl - lcrypt -lm -lc ~/hello$ ls depends extconf.rb hello.c hello.o hello.so 2007-11-17 Ruby 勉強会@札幌 #6 13
  • 15. 使ってみる 使ってみる ~/hello$ irb void irb(main):001:0> require 'hello' Init_hello(void) [XXX] Init_hello { => true VALUE cHello; irb(main):002:0> h = Hello.new => #<Hello:0xb7c7e590> printf(quot;[XXX] Init_hello¥nquot;); irb(main):003:0> h.hello ====================================== [XXX] hello_hello static VALUE hello, world hello_hello(VALUE self) => #<Hello:0xb7c7e590> { irb(main):004:0> exit VALUE str; ~/hello$ printf(quot;[XXX] hello_hello¥nquot;); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return self; } 2007-11-17 Ruby 勉強会@札幌 #6 14
  • 16. ここまでのまとめ (1) ここまでのまとめ (1) クラスを定義する rb_define_class(クラス名, 親クラスオブジェクト) クラスにインスタンスメソッドを定義する rb_define_method( クラスオブジェクト, メソッド名, メソッドを実装している関数, 引数の個数) 2007-11-17 Ruby 勉強会@札幌 #6 15
  • 17. ここまでのまとめ (2) ここまでのまとめ (2) メソッドの実体となる関数 (hello_hello) 第1仮引数・・・レシーバオブジェクト その他・・・メソッドの引数 Ruby の⽂字列オブジェクトを⽣成する rb_str_new2(C の⽂字列) puts rb_io_puts(1, &⽂字列, rb_stdout) • 本当は rb_io_puts(argc, argv, rb_stdout) で,argv が puts に渡す実引数の C 配列,argc がその⻑さ 2007-11-17 Ruby 勉強会@札幌 #6 16
  • 18. 拡張モジュールを 拡張モジュールを 作る前に 作る前に そんなに難しくないよ 17 2007-11-17 Ruby 勉強会@札幌 #6
  • 19. おちついて⼀読すべし おちついて⼀読すべし Ruby には拡張モジュールの作り⽅のドキュメ ントがもれなくついてくる! README.EXT README.EXT.ja 2007-11-17 Ruby 勉強会@札幌 #6 18
  • 20. 拡張モジュールを作るとは 拡張モジュールを作るとは どういうことか? どういうことか? Ruby インタプリタが理解できることば 構⽂⽊ C ⾔語 拡張モジュールを作る = Ruby インタプリタとお喋りする 2007-11-17 Ruby 勉強会@札幌 #6 19
  • 21. 参考になるものたち 参考になるものたち Ruby のソースを読むべし! array.c hash.c object.c string.c よく使うクラスを実装しているコードを読むことで 拡張モジュール作成のための知識を増やそう 2007-11-17 Ruby 勉強会@札幌 #6 20
  • 22. まとめ まとめ MA☆TO☆めけーも 21 2007-11-17 Ruby 勉強会@札幌 #6
  • 23. 拡張モジュールを作ろう! C ⾔語で Ruby とお喋りしよう 2007-11-17 Ruby 勉強会@札幌 #6 22