SlideShare a Scribd company logo
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

More Related Content

More from Kenta Murata

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

More from Kenta Murata (12)

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

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