SlideShare a Scribd company logo
1 of 27
Download to read offline
Rubyの黒魔術
              とみたまさひろ
                2010-03-13



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

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

                                      2/26
Rubyの黒魔術                   Powered by Rabbit 0.6.4
自己紹介




           こんな本書きました

                                  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 Rabbit 0.6.4
動的:
  黒魔術
Rubyの黒魔術
                      6/26
           Powered by Rabbit 0.6.4
メソッドが実行時に生成される

           hoge(123) #=> エラー
           def hoge(v)
           end
           ------------------------
           def hoge(v)
           end
           hoge(123) #=> OK
                                             7/26
Rubyの黒魔術                          Powered by Rabbit 0.6.4
クラスが実行時に生成される

           A.new #=> エラー
           class A
           end
           ------------------------
           class A
           end
           A.new #=> OK
                                             8/26
Rubyの黒魔術                          Powered by Rabbit 0.6.4
パース時ではなくて実行時


           if rand(2) == 0
             class A < String; end
           else
             class A < Integer; end
           end

                                             9/26
Rubyの黒魔術                          Powered by Rabbit 0.6.4
オープンクラス
   既存のクラスを変更できる

           class String
             def balse!
               puts "目が、目がぁ!"
             end
           end
           "ムスカ".balse!
                                    10/26
Rubyの黒魔術                    Powered by Rabbit 0.6.4
特異メソッド

   特定のオブジェクトだけにメソッド追加
           musuka = "ムスカ"
           def musuka.balse!
             puts "目が、目がぁ!"
           end
           musuka.balse!
           "レプカ".balse! # undefined method `balse!'


                                                       11/26
Rubyの黒魔術                                       Powered by Rabbit 0.6.4
演算子もメソッド
           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
クラスもオブジェクト


           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
メソッドも動的に生成

           class Hoge
             define_method :hoge do
               123
             end
           end
           Hoge.new.hoge #=> 123

                                          14/26
Rubyの黒魔術                          Powered by Rabbit 0.6.4
たとえばこんな感じ

           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
定数の動的取得


           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
文字列からメソッド呼び出し

           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
宣言っぽいもの


           define_attribute :port do
             range 1..65535
             description 'TCP/IP port number'
           end


                                                 18/26
Rubyの黒魔術                                 Powered by Rabbit 0.6.4
宣言っぽいもの
           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
設定ファイル

           $proto = "smtp"
           $hostname = "example.com"
           $port = 25
   ↑を load "filename"
   グローバル変数はちょっと…
                                          20/26
Rubyの黒魔術                          Powered by Rabbit 0.6.4
設定ファイル
   ハッシュとか

           $conf = {
             :proto    => "smtp",
             :hostname => "example.com",
             :port     => 25,
           }
   ↑を load "filename"
   設定ファイルっぽくない。                              21/26
Rubyの黒魔術                             Powered by Rabbit 0.6.4
設定ファイル


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

                                            22/26
Rubyの黒魔術                            Powered by Rabbit 0.6.4
設定ファイル
           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
その他
     ✓ クラスが継承された時に実行され
       るメソッド
     ✓ メソッドが存在しない時に実行さ
       れるメソッド
     ✓ メソッドが追加/削除された時に
       実行されるメソッド
     ✓ クラスの祖先を調べる
     ✓ オブジェクトにメソッドがあるか?24/26
Rubyの黒魔術               Powered by Rabbit 0.6.4
黒魔術も
    正しく使え
    ば白魔術
Rubyの黒魔術
                   25/26
           Powered by Rabbit 0.6.4
ご清聴あり
  がとうござ
   いました
Rubyの黒魔術
                   26/26
           Powered by Rabbit 0.6.4

More Related Content

What's hot

セグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイント
セグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイントセグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイント
セグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイント
Naoto Tamiya
 

What's hot (20)

テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
Test Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるかTest Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるか
 
modern software qa - draft 1
modern software qa - draft 1modern software qa - draft 1
modern software qa - draft 1
 
IT系エンジニアのためのプレゼンテーション入門
IT系エンジニアのためのプレゼンテーション入門IT系エンジニアのためのプレゼンテーション入門
IT系エンジニアのためのプレゼンテーション入門
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
見やすいプレゼン資料の作り方 - リニューアル増量版
見やすいプレゼン資料の作り方 - リニューアル増量版見やすいプレゼン資料の作り方 - リニューアル増量版
見やすいプレゼン資料の作り方 - リニューアル増量版
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
研究分野をサーベイする
研究分野をサーベイする研究分野をサーベイする
研究分野をサーベイする
 
cvpaper.challenge 研究効率化 Tips
cvpaper.challenge 研究効率化 Tipscvpaper.challenge 研究効率化 Tips
cvpaper.challenge 研究効率化 Tips
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
 
研究発表のためのパワーポイント資料作成の基本
研究発表のためのパワーポイント資料作成の基本研究発表のためのパワーポイント資料作成の基本
研究発表のためのパワーポイント資料作成の基本
 
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Lean coffee
Lean coffeeLean coffee
Lean coffee
 
【プレゼン】見やすいプレゼン資料の作り方【初心者用】
【プレゼン】見やすいプレゼン資料の作り方【初心者用】【プレゼン】見やすいプレゼン資料の作り方【初心者用】
【プレゼン】見やすいプレゼン資料の作り方【初心者用】
 
セグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイント
セグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイントセグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイント
セグメント?クラスタリング? ユーザーを分類し、サービスの改善に活かすポイント
 
私にとってのテスト
私にとってのテスト私にとってのテスト
私にとってのテスト
 
研究発表を準備する(2022年版)
研究発表を準備する(2022年版)研究発表を準備する(2022年版)
研究発表を準備する(2022年版)
 
アジャイルな受託開発のみらい
アジャイルな受託開発のみらいアジャイルな受託開発のみらい
アジャイルな受託開発のみらい
 

More from Masahiro Tomita

「理論から学ぶデータベース実践入門」読書会スペシャル
「理論から学ぶデータベース実践入門」読書会スペシャル「理論から学ぶデータベース実践入門」読書会スペシャル
「理論から学ぶデータベース実践入門」読書会スペシャル
Masahiro Tomita
 
アジャイルジャパン長野サテライト
アジャイルジャパン長野サテライトアジャイルジャパン長野サテライト
アジャイルジャパン長野サテライト
Masahiro Tomita
 

More from Masahiro Tomita (20)

お前の罪を数えろ
お前の罪を数えろお前の罪を数えろ
お前の罪を数えろ
 
Ruby 2.5
Ruby 2.5Ruby 2.5
Ruby 2.5
 
本当はこわいMySQLプロトコル
本当はこわいMySQLプロトコル本当はこわいMySQLプロトコル
本当はこわいMySQLプロトコル
 
ネットワークこわい
ネットワークこわいネットワークこわい
ネットワークこわい
 
CSV
CSVCSV
CSV
 
MySQLの文字コード事情 2017春版
MySQLの文字コード事情 2017春版MySQLの文字コード事情 2017春版
MySQLの文字コード事情 2017春版
 
MySQLの文字コード事情 2017版
MySQLの文字コード事情 2017版MySQLの文字コード事情 2017版
MySQLの文字コード事情 2017版
 
Ruby24
Ruby24Ruby24
Ruby24
 
MySQLの文字コード事情
MySQLの文字コード事情MySQLの文字コード事情
MySQLの文字コード事情
 
進捗と品質
進捗と品質進捗と品質
進捗と品質
 
MySQLを拡張する
MySQLを拡張するMySQLを拡張する
MySQLを拡張する
 
「理論から学ぶデータベース実践入門」読書会スペシャル
「理論から学ぶデータベース実践入門」読書会スペシャル「理論から学ぶデータベース実践入門」読書会スペシャル
「理論から学ぶデータベース実践入門」読書会スペシャル
 
MyNAができるまで
MyNAができるまでMyNAができるまで
MyNAができるまで
 
文字化け
文字化け文字化け
文字化け
 
Crystal
CrystalCrystal
Crystal
 
メールの暗号化
メールの暗号化メールの暗号化
メールの暗号化
 
文字化け
文字化け文字化け
文字化け
 
進捗と品質
進捗と品質進捗と品質
進捗と品質
 
アジャイルジャパン長野サテライト
アジャイルジャパン長野サテライトアジャイルジャパン長野サテライト
アジャイルジャパン長野サテライト
 
🍣=🍺
🍣=🍺🍣=🍺
🍣=🍺
 

Recently uploaded

Recently uploaded (10)

新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 

Rubyの黒魔術

  • 1. Rubyの黒魔術 とみたまさひろ 2010-03-13 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 2. 自己紹介 ✓ とみた まさひろ ✓ プログラマー ✓ mailto:tommy@tmtm.org ✓ id:tmtms ✓ @tmtms 1/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 3. 自己紹介 ✓ 日本Rubyの会 ✓ 日本MySQLユーザ会 ✓ Ruby/MySQL ライブラリ ✓ Ruby歴, MySQL歴 十数年 2/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 4. 自己紹介 こんな本書きました 3/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 5. Ruby 4/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 6. Rubyの特徴 ✓ オブジェクト指向 ✓ スクリプト ✓ 動的 5/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 7. 動的: 黒魔術 Rubyの黒魔術 6/26 Powered by Rabbit 0.6.4
  • 8. メソッドが実行時に生成される hoge(123) #=> エラー def hoge(v) end ------------------------ def hoge(v) end hoge(123) #=> OK 7/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 9. クラスが実行時に生成される A.new #=> エラー class A end ------------------------ class A end A.new #=> OK 8/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 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. オープンクラス 既存のクラスを変更できる class String def balse! puts "目が、目がぁ!" end end "ムスカ".balse! 10/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 12. 特異メソッド 特定のオブジェクトだけにメソッド追加 musuka = "ムスカ" def musuka.balse! puts "目が、目がぁ!" end musuka.balse! "レプカ".balse! # undefined method `balse!' 11/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 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. クラスもオブジェクト 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. メソッドも動的に生成 class Hoge define_method :hoge do 123 end end Hoge.new.hoge #=> 123 14/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 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. 定数の動的取得 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. 文字列からメソッド呼び出し 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. 宣言っぽいもの define_attribute :port do range 1..65535 description 'TCP/IP port number' end 18/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 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. 設定ファイル $proto = "smtp" $hostname = "example.com" $port = 25 ↑を load "filename" グローバル変数はちょっと… 20/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 22. 設定ファイル ハッシュとか $conf = { :proto => "smtp", :hostname => "example.com", :port => 25, } ↑を load "filename" 設定ファイルっぽくない。 21/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 23. 設定ファイル proto "smtp" hostname "example.com" port 25 これを eval 22/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 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. その他 ✓ クラスが継承された時に実行され るメソッド ✓ メソッドが存在しない時に実行さ れるメソッド ✓ メソッドが追加/削除された時に 実行されるメソッド ✓ クラスの祖先を調べる ✓ オブジェクトにメソッドがあるか?24/26 Rubyの黒魔術 Powered by Rabbit 0.6.4
  • 26. 黒魔術も 正しく使え ば白魔術 Rubyの黒魔術 25/26 Powered by Rabbit 0.6.4
  • 27. ご清聴あり がとうござ いました Rubyの黒魔術 26/26 Powered by Rabbit 0.6.4