e-Zuka Teck Night Vol.1Ruby                      のクロージャとファイバーをかっこよく使ってみようe-Zuka Teck Night, Rubyist九州   近畿大学            山崎...
e-Zuka Teck Night Vol.1            Rubyには          関数型言語の         顔があるんです 1.9になってますます関数型言語的な感じ closureやFiberはそんな感じが強い 今...
e-Zuka Teck Night Vol.1関数定義λを使って関数を定義すると    ->x{ … }
e-Zuka Teck Night Vol.1無名関数の使い方> ->x{x+1}   #Procオブジェクト> ->x{x+1}[3] #関数適用4
e-Zuka Teck Night Vol.1Rubyの文法をちょっと 繰り返し構造を持つオブジェクトの例イテレータ (1..5)    #範囲ブジェクト オブジェクト自体の繰り返し構造にそって繰り返しを制御 [1,2,3,4,5] #配列>...
e-Zuka Teck Night Vol.1関数に名前をつけるProcを代入する 階乗関数の例 fact =->n{n==0?1:(1..n).reduce(:*)}
e-Zuka Teck Night Vol.1関数とクロージャ関数の独立変数と係数は何が違うのか?  f(x) = a*x アルファベットの前の方が係数で終わりの方が変数?
e-Zuka Teck Night Vol.1λとレキシカル変数ラムダは「これが変数だ」という束縛を表示する  f = ->x{a*x}束縛されていない変数   aは、「レキシカル変数」
e-Zuka Teck Night Vol.1レキシカル変数の例> a=1> ->x{a=a*x}}[10]10>a10
e-Zuka Teck Night Vol.1レキシコン:辞書の語彙レキシカル変数とは、辞書の項目の意味文字列 →      束縛されている値eval するとその環境の辞書におけるレキシカル変数の 値がわかる> age = 54> eval...
e-Zuka Teck Night Vol.1関数の関数の定義λを二つ使うと(関数の関数)->x{->y{...}}
e-Zuka Teck Night Vol.1レキシカル変数とクロージャ 係数   a を関数の関数の束縛変数として定義する場合  f= ->a{->x{a*x}}
e-Zuka Teck Night Vol.1関数の関数でクロージャをつくる組合せ関数 2引数(nとr)combi=->n{->r{fact[n]/(fact[r]*fact[n-r])}}> combi[8][4]70> c8=combi[8...
e-Zuka Teck Night Vol.1関数に辞書(環境)が含まれている(クロージャ)> eval(n,c8.binding)>8> n=1000> eval(n,c8.binding)>8
e-Zuka Teck Night Vol.1レキシカルスコープ変数の辞書に一旦定義されるとその後は、ずっと内側の世界でも同じ辞書を使う内側の世界の辞書は外からは隠蔽されている     a=1     a=10 代入      a=10 ...
e-Zuka Teck Night Vol.1関数のメモ化は、xが未定義の時だけobj                                x||=objクロージャでキャッシュが作れる             を代入するという意味組...
e-Zuka Teck Night Vol.1Fiber                  #子スレッド(ファイバー)                       f=Fiber.new{|x|                         ...
e-Zuka Teck Night Vol.1Fiberによる親子コミュニケーションファイバー(子スレッド)の生成f=Fiber.new{|x| loop{x=Fiber.yield(x+1)}}親スレッドからファイバー(子スレッド)にメッセー...
e-Zuka Teck Night Vol.1Fiberによるジェネレータ無限集合などをあつかうプログラム自然数ジェネレータnum=->a{loop{a+=1}}> num[0] #... 無限ループ〜無限集合を素直に生成しているんだけどねフ...
e-Zuka Teck Night Vol.1Fiberによるジェネレータフィボナッチ数列バージョン!fib=->{a,b=0,1;loop{a,b=b,a+b}}>fib[]... 無限ループ〜ファイバーにするf=Fiber.new{a,b...
e-Zuka Teck Night Vol.1Generate and Test素数生成の例> num=->a{Fiber.new{loop{Fiber.yield a+=1}}}> numg=num[1]             #2以上の...
e-Zuka Teck Night Vol.1    Fiber による    ジェネレータ素数バージョン(しつこい!)prime =->n{p=[];loop{p.push n if p.all?{|x|n%x!=0};n+=1}}>pri...
e-Zuka Teck Night Vol.1ノンプリエンプティブなマルチタスクOSに頼らない(負荷が軽い)ファイバーにした自然数ジェネレータnum1=Fiber.new{|a| loop{Fiber.yield a+=1}}num2=Fib...
e-Zuka Teck Night Vol.1コルーチンとしてのFiber初期のMacintosh OS 多数のコルーチンの集合体でできていた                            Macintosh 128K (超軽量スレッ...
e-Zuka Teck Night Vol.1FiberでコルーチンWebサーバの超軽量化イベント処理をコルーチンPoolに事前に生成しておくメモリ節約、レスポンスの高速化                    Pjaxなどの        ...
e-Zuka Teck Night Vol.1      FiberとThreadの比較 出典:Ruby Fibers Vs Ruby Threads  http://oldmoe.blogspot.com/2008/08/ruby-fibe...
e-Zuka Teck Night Vol.1Fiberでリアルタイム処理3軸加速度センサーのバッファ入力の例#バッファ管理クロージャbf=->a{->d{a.push(d).shift; a}}#ファイバー生成関数bff=->a{b=bf[...
e-Zuka Teck Night Vol.1Fiberによるリアルタイム処理3つじゃあまりありがたくない1000個のセンサーの入力をサーバでリアルタイム処理群衆や流体のシミュレーションにもJavaScritptやprocessingの方が...
e-Zuka Teck Night Vol.1コールバックスパゲティを改善するJavaScriptでブラウザの制御を書くと コルーチン登録タイミングの空振り コールバックルーチンがコールバックルーチンを呼ぶjavaScript 1.7で F...
e-Zuka Teck Night Vol.1まとめ細粒度イベント駆動型Web (Pjaxなど)センサー/機械制御系/ロボットシミュレーションジェネレータを使う知的システムマウスでごりごり型ファイバーをうまく使うとそういうタイプのプロ...
Upcoming SlideShare
Loading in …5
×

Ruby1.9のfiberのかっこよくつかおう

4,574 views

Published on

0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,574
On SlideShare
0
From Embeds
0
Number of Embeds
27
Actions
Shares
0
Downloads
7
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Ruby1.9のfiberのかっこよくつかおう

  1. 1. e-Zuka Teck Night Vol.1Ruby のクロージャとファイバーをかっこよく使ってみようe-Zuka Teck Night, Rubyist九州 近畿大学 山崎重一郎
  2. 2. e-Zuka Teck Night Vol.1 Rubyには 関数型言語の 顔があるんです 1.9になってますます関数型言語的な感じ closureやFiberはそんな感じが強い 今日はRubyをオブジェクト指向言語じゃなくて関 数型言語みたいに扱います!
  3. 3. e-Zuka Teck Night Vol.1関数定義λを使って関数を定義すると ->x{ … }
  4. 4. e-Zuka Teck Night Vol.1無名関数の使い方> ->x{x+1} #Procオブジェクト> ->x{x+1}[3] #関数適用4
  5. 5. e-Zuka Teck Night Vol.1Rubyの文法をちょっと 繰り返し構造を持つオブジェクトの例イテレータ (1..5) #範囲ブジェクト オブジェクト自体の繰り返し構造にそって繰り返しを制御 [1,2,3,4,5] #配列> (1..5).map{|x| x*100} #イテレータmap[100, 200, 300, 400, 500]> (1..5).reduce{|s,x|s+=x} #イテレータreduce15
  6. 6. e-Zuka Teck Night Vol.1関数に名前をつけるProcを代入する 階乗関数の例 fact =->n{n==0?1:(1..n).reduce(:*)}
  7. 7. e-Zuka Teck Night Vol.1関数とクロージャ関数の独立変数と係数は何が違うのか? f(x) = a*x アルファベットの前の方が係数で終わりの方が変数?
  8. 8. e-Zuka Teck Night Vol.1λとレキシカル変数ラムダは「これが変数だ」という束縛を表示する f = ->x{a*x}束縛されていない変数 aは、「レキシカル変数」
  9. 9. e-Zuka Teck Night Vol.1レキシカル変数の例> a=1> ->x{a=a*x}}[10]10>a10
  10. 10. e-Zuka Teck Night Vol.1レキシコン:辞書の語彙レキシカル変数とは、辞書の項目の意味文字列 → 束縛されている値eval するとその環境の辞書におけるレキシカル変数の 値がわかる> age = 54> eval(age)54
  11. 11. e-Zuka Teck Night Vol.1関数の関数の定義λを二つ使うと(関数の関数)->x{->y{...}}
  12. 12. e-Zuka Teck Night Vol.1レキシカル変数とクロージャ 係数 a を関数の関数の束縛変数として定義する場合 f= ->a{->x{a*x}}
  13. 13. e-Zuka Teck Night Vol.1関数の関数でクロージャをつくる組合せ関数 2引数(nとr)combi=->n{->r{fact[n]/(fact[r]*fact[n-r])}}> combi[8][4]70> c8=combi[8] # nが8のクロージャをつくる> (0..8).map{|x| c8[x]} #いろんなrでの結果[1, 8, 28, 56, 70, 56, 28, 8, 1]
  14. 14. e-Zuka Teck Night Vol.1関数に辞書(環境)が含まれている(クロージャ)> eval(n,c8.binding)>8> n=1000> eval(n,c8.binding)>8
  15. 15. e-Zuka Teck Night Vol.1レキシカルスコープ変数の辞書に一旦定義されるとその後は、ずっと内側の世界でも同じ辞書を使う内側の世界の辞書は外からは隠蔽されている a=1 a=10 代入 a=10 a→10 a→未定義 a→10 a→未定義
  16. 16. e-Zuka Teck Night Vol.1関数のメモ化は、xが未定義の時だけobj x||=objクロージャでキャッシュが作れる を代入するという意味組み合わせ関数のメモ化c=->m{->n{m[n]||={};->r{m[n][r]||=combi[n][r]}}}> cm=c[{}] #空のハッシュオブジェクトで初期化> cm[80000][79990] 2957280616639006757538254376469462127992000> eval(m,cm.binding){80000=>{79990=>2957280616639006757538254376469462127992000}}
  17. 17. e-Zuka Teck Night Vol.1Fiber #子スレッド(ファイバー) f=Fiber.new{|x| puts 最初 Fiber.yield軽量スレッドと継続 puts x• Fiber.new{|x|...} y=Fiber.yield ファイバーの生成 puts y =子スレッド(軽量) } #親スレッド• Fiver.yield(obj) > f.resume 3 親のコンテクストに行く 最初 > f.resume• resume(obj) メソッド 3 子供のコンテクストに行く > f.resume 7 (停止中の処理を継続) 7 > f.resume FiberError: dead fiber called
  18. 18. e-Zuka Teck Night Vol.1Fiberによる親子コミュニケーションファイバー(子スレッド)の生成f=Fiber.new{|x| loop{x=Fiber.yield(x+1)}}親スレッドからファイバー(子スレッド)にメッセージを出すとファイバーがそれに応える> f.resume 100101> f.resume 23
  19. 19. e-Zuka Teck Night Vol.1Fiberによるジェネレータ無限集合などをあつかうプログラム自然数ジェネレータnum=->a{loop{a+=1}}> num[0] #... 無限ループ〜無限集合を素直に生成しているんだけどねファイバーにした自然数ジェネレータnum=Fiber.new{|a| loop{Fiber.yield a+=1}}> num.resume 01> num.resume2
  20. 20. e-Zuka Teck Night Vol.1Fiberによるジェネレータフィボナッチ数列バージョン!fib=->{a,b=0,1;loop{a,b=b,a+b}}>fib[]... 無限ループ〜ファイバーにするf=Fiber.new{a,b=0,1;loop{Fiber.yield a;a,b=b,a+b}}> 5.times {puts f.resume}01123
  21. 21. e-Zuka Teck Night Vol.1Generate and Test素数生成の例> num=->a{Fiber.new{loop{Fiber.yield a+=1}}}> numg=num[1] #2以上の自然数のジェネレータprime=->pl{->{ begin n=numg.resume #自然数ジェネレータ end until pl.all?{|x|n%x!=0} #テスト pl.push n}}> pr=prime[[]]> pr[][2]> pr[]
  22. 22. e-Zuka Teck Night Vol.1 Fiber による ジェネレータ素数バージョン(しつこい!)prime =->n{p=[];loop{p.push n if p.all?{|x|n%x!=0};n+=1}}>prime[2]ファイバー版fprime=Fiber.new{|n|p=[]; loop{Fiber.yield p.push(n).last if p.all?{|x|n%x!=0};n+=1}}> fprime.resume 22> fprime.resume3
  23. 23. e-Zuka Teck Night Vol.1ノンプリエンプティブなマルチタスクOSに頼らない(負荷が軽い)ファイバーにした自然数ジェネレータnum1=Fiber.new{|a| loop{Fiber.yield a+=1}}num2=Fiber.new{|a| loop{Fiber.yield a+=1}}> num1.resume 01> num2.resume 01> num1.resume2> num2.resume2
  24. 24. e-Zuka Teck Night Vol.1コルーチンとしてのFiber初期のMacintosh OS 多数のコルーチンの集合体でできていた Macintosh 128K (超軽量スレッド) 8MHz 128Kb 操作による イベント 実際のメモリ ビットマップ への表示など
  25. 25. e-Zuka Teck Night Vol.1FiberでコルーチンWebサーバの超軽量化イベント処理をコルーチンPoolに事前に生成しておくメモリ節約、レスポンスの高速化 Pjaxなどの 細粒度イベント ブラウザ 操作による イベント POSTとか Fiber対応Webサーバ ブラウザへの Goliathとか 表示変更
  26. 26. e-Zuka Teck Night Vol.1 FiberとThreadの比較 出典:Ruby Fibers Vs Ruby Threads http://oldmoe.blogspot.com/2008/08/ruby-fibers-vs-ruby-threads.html
  27. 27. e-Zuka Teck Night Vol.1Fiberでリアルタイム処理3軸加速度センサーのバッファ入力の例#バッファ管理クロージャbf=->a{->d{a.push(d).shift; a}}#ファイバー生成関数bff=->a{b=bf[a]; Fiber.new{|d|loop{d=Fiber.yield b[d]}}}fx=bff[Array.new(10,0.0)] #x軸方向fy=bff[Array.new(10,0.0)] #y軸方向fz=bff[Array.new(10,0.0)] #z軸方向loop do data=sp.readline.split(,).map {|x| x.to_f} fx.resume(data[0]) fy.resume(data[1]) fz.resume(data[2])end
  28. 28. e-Zuka Teck Night Vol.1Fiberによるリアルタイム処理3つじゃあまりありがたくない1000個のセンサーの入力をサーバでリアルタイム処理群衆や流体のシミュレーションにもJavaScritptやprocessingの方がいいかもしれないけど
  29. 29. e-Zuka Teck Night Vol.1コールバックスパゲティを改善するJavaScriptでブラウザの制御を書くと コルーチン登録タイミングの空振り コールバックルーチンがコールバックルーチンを呼ぶjavaScript 1.7で Fiber (yield, next) が仕様に追加され た(いまのところ実装されているのはfirefoxだけ) 将来的には、マウスでぐりぐりやるようなプログラムはFiber で書くようになるでしょう。
  30. 30. e-Zuka Teck Night Vol.1まとめ細粒度イベント駆動型Web (Pjaxなど)センサー/機械制御系/ロボットシミュレーションジェネレータを使う知的システムマウスでごりごり型ファイバーをうまく使うとそういうタイプのプログラムをすっきり書ける!

×