Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Rubyの黒魔術
              とみたまさひろ
                2010-03-13



Rubyの黒魔術            Powered by Rabbit 0.6.4
自己紹介
     ✓ とみた まさひろ
     ✓ プログラマー
     ✓ mailto:tommy@tmtm.org
     ✓ id:tmtms
     ✓ @tmtms
                            ...
自己紹介

     ✓ 日本Rubyの会
     ✓ 日本MySQLユーザ会
     ✓ Ruby/MySQL ライブラリ
     ✓ Ruby歴, MySQL歴 十数年

                               ...
自己紹介




           こんな本書きました

                                  3/26
Rubyの黒魔術               Powered by Rabbit 0.6.4
Ruby                4/26
Rubyの黒魔術   Powered by Rabbit 0.6.4
Rubyの特徴


     ✓ オブジェクト指向
     ✓ スクリプト
     ✓ 動的


                                 5/26
Rubyの黒魔術              Powered by ...
動的:
  黒魔術
Rubyの黒魔術
                      6/26
           Powered by Rabbit 0.6.4
メソッドが実行時に生成される

           hoge(123) #=> エラー
           def hoge(v)
           end
           ------------------------
   ...
クラスが実行時に生成される

           A.new #=> エラー
           class A
           end
           ------------------------
           c...
パース時ではなくて実行時


           if rand(2) == 0
             class A < String; end
           else
             class A < Intege...
オープンクラス
   既存のクラスを変更できる

           class String
             def balse!
               puts "目が、目がぁ!"
             end
  ...
特異メソッド

   特定のオブジェクトだけにメソッド追加
           musuka = "ムスカ"
           def musuka.balse!
             puts "目が、目がぁ!"
         ...
演算子もメソッド
           3+5      #=> 8
           3.+(5)   #=> 8
           # 既存の演算子の書き換えも可能
           class Fixnum
         ...
クラスもオブジェクト


           c = Class.new(SuperClass)   # 名無しクラス
           p c       #=> #<Class:0xb744ac84>
           c.new...
メソッドも動的に生成

           class Hoge
             define_method :hoge do
               123
             end
           end
 ...
たとえばこんな感じ

           class A
             [:hoge, :fuga, :hage].each do |name|
               define_method name do
     ...
定数の動的取得


           class Hoge
             C = 123
             D = "abc"
           end
           Hoge.constants      ...
文字列からメソッド呼び出し

           name = "HogeFuga/nanika"
           cname, mname = name.split('/')
           lib = cname.gsub(/...
宣言っぽいもの


           define_attribute :port do
             range 1..65535
             description 'TCP/IP port number'
 ...
宣言っぽいもの
           def define_attribute(name, &block)
             Attribute.new(&block)
           end
           class A...
設定ファイル

           $proto = "smtp"
           $hostname = "example.com"
           $port = 25
   ↑を load "filename"
   グロー...
設定ファイル
   ハッシュとか

           $conf = {
             :proto    => "smtp",
             :hostname => "example.com",
        ...
設定ファイル


           proto "smtp"
           hostname "example.com"
           port 25
   これを eval

                       ...
設定ファイル
           class Config
             def initialize(filename)
               eval File.read(filename)
             ...
その他
     ✓ クラスが継承された時に実行され
       るメソッド
     ✓ メソッドが存在しない時に実行さ
       れるメソッド
     ✓ メソッドが追加/削除された時に
       実行されるメソッド
     ...
黒魔術も
    正しく使え
    ば白魔術
Rubyの黒魔術
                   25/26
           Powered by Rabbit 0.6.4
ご清聴あり
  がとうござ
   いました
Rubyの黒魔術
                   26/26
           Powered by Rabbit 0.6.4
Upcoming SlideShare
Loading in …5
×

Rubyの黒魔術

22,057 views

Published on

NSEG第1回勉強会 http://kokucheese.com/event/index/1654/ で発表したネタ

Published in: Technology

Rubyの黒魔術

  1. 1. Rubyの黒魔術 とみたまさひろ 2010-03-13 Rubyの黒魔術 Powered by Rabbit 0.6.4
  2. 2. 自己紹介 ✓ とみた まさひろ ✓ プログラマー ✓ mailto:tommy@tmtm.org ✓ id:tmtms ✓ @tmtms 1/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  3. 3. 自己紹介 ✓ 日本Rubyの会 ✓ 日本MySQLユーザ会 ✓ Ruby/MySQL ライブラリ ✓ Ruby歴, MySQL歴 十数年 2/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  4. 4. 自己紹介 こんな本書きました 3/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  5. 5. Ruby 4/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  6. 6. Rubyの特徴 ✓ オブジェクト指向 ✓ スクリプト ✓ 動的 5/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  7. 7. 動的: 黒魔術 Rubyの黒魔術 6/26 Powered by Rabbit 0.6.4
  8. 8. メソッドが実行時に生成される hoge(123) #=> エラー def hoge(v) end ------------------------ def hoge(v) end hoge(123) #=> OK 7/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  9. 9. クラスが実行時に生成される A.new #=> エラー class A end ------------------------ class A end A.new #=> OK 8/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  10. 10. パース時ではなくて実行時 if rand(2) == 0 class A < String; end else class A < Integer; end end 9/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  11. 11. オープンクラス 既存のクラスを変更できる class String def balse! puts "目が、目がぁ!" end end "ムスカ".balse! 10/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  12. 12. 特異メソッド 特定のオブジェクトだけにメソッド追加 musuka = "ムスカ" def musuka.balse! puts "目が、目がぁ!" end musuka.balse! "レプカ".balse! # undefined method `balse!' 11/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  13. 13. 演算子もメソッド 3+5 #=> 8 3.+(5) #=> 8 # 既存の演算子の書き換えも可能 class Fixnum def +(n) self * n end end 3+5 #=> 15 12/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  14. 14. クラスもオブジェクト c = Class.new(SuperClass) # 名無しクラス p c #=> #<Class:0xb744ac84> c.new # ちゃんとクラス Hoge = c # 定数に代入すると名前がつく p c #=> Hoge Hoge.new 13/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  15. 15. メソッドも動的に生成 class Hoge define_method :hoge do 123 end end Hoge.new.hoge #=> 123 14/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  16. 16. たとえばこんな感じ class A [:hoge, :fuga, :hage].each do |name| define_method name do name.to_s.capitalize end end end A.new.hoge #=> "Hoge" A.new.fuga #=> "Fuga" 15/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  17. 17. 定数の動的取得 class Hoge C = 123 D = "abc" end Hoge.constants #=> ["D", "C"] Hoge.const_get("C") #=> 123 16/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  18. 18. 文字列からメソッド呼び出し name = "HogeFuga/nanika" cname, mname = name.split('/') lib = cname.gsub(/([A-Z])/,'_1'). downcase.sub(/^_/,'') #=> "hoge_fuga" require lib klass = self.class.const_get(cname) obj = klass.new obj.method(mname).call 17/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  19. 19. 宣言っぽいもの define_attribute :port do range 1..65535 description 'TCP/IP port number' end 18/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  20. 20. 宣言っぽいもの def define_attribute(name, &block) Attribute.new(&block) end class Attribute def initialize(&block) self.instance_eval &block end def range(r) ... end def description(d) ... end end 19/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  21. 21. 設定ファイル $proto = "smtp" $hostname = "example.com" $port = 25 ↑を load "filename" グローバル変数はちょっと… 20/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  22. 22. 設定ファイル ハッシュとか $conf = { :proto => "smtp", :hostname => "example.com", :port => 25, } ↑を load "filename" 設定ファイルっぽくない。 21/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  23. 23. 設定ファイル proto "smtp" hostname "example.com" port 25 これを eval 22/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  24. 24. 設定ファイル class Config def initialize(filename) eval File.read(filename) end def proto(p) ... end def hostname(h) ... end def port(n) ... end end 23/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  25. 25. その他 ✓ クラスが継承された時に実行され るメソッド ✓ メソッドが存在しない時に実行さ れるメソッド ✓ メソッドが追加/削除された時に 実行されるメソッド ✓ クラスの祖先を調べる ✓ オブジェクトにメソッドがあるか?24/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  26. 26. 黒魔術も 正しく使え ば白魔術 Rubyの黒魔術 25/26 Powered by Rabbit 0.6.4
  27. 27. ご清聴あり がとうござ いました Rubyの黒魔術 26/26 Powered by Rabbit 0.6.4

×