Your SlideShare is downloading. ×
0
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

怠惰なRubyistへの道 fukuoka rubykaigi01

505

Published on

福岡Ruby会議01 で発表したスライドを公開用にPDF に変換したものです。アニメーションやデモ動画はスライドに置き換えています。

福岡Ruby会議01 で発表したスライドを公開用にPDF に変換したものです。アニメーションやデモ動画はスライドに置き換えています。

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
505
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 怠惰なRubyistへの道Enumerator::Lazyの使いかた Chikanaga Tomoyuki (@nagachika) Fukuoka.rb 2012.12.1 Fukuoka Ruby Kaigi 01
  • 2. AgendaEnumerableEnumeratorEnumerator::Lazy
  • 3. AgendaEnumerable2.0 の新機能(NEW)EnumeratorEnumerator::Lazy
  • 4. ATTENTION 今日の話は Ruby 2.0 の新機能について
  • 5. Ruby 2.02013年リリース予定[ruby-dev:44691] よりAug. 24 2012: big-feature freezeOct. 24 2012: feature freezeFeb. 24 2013: 2.0 releaseRuby の生誕 20 周年
  • 6. Ruby 2.0Aug. 24 2012: big-feature freezeOct. 24 2012: feature freezeNov. 2 2012: 2.0 preview1 released←今ココDec. 1 2012: 2.0 preview2 releasedFeb. 24 2013: 2.0 release
  • 7. 2.0 is in development ※注※ 仕様は開発中のものでありリリース版では変更される場合があります
  • 8. Install Ruby 2.02.0.0 で未来を垣間見るrvm, rbenv を使っていればrvm install ruby-headrbenv install 2.0-devel
  • 9. Self Introductiontwitter id: @nagachikaruby trunk changes(http://d.hatena.ne.jp/nagachika)CRuby committerYokohama.rb → Fukuoka.rbSound.rb(ruby-coreaudio, ruby-puredata)
  • 10. Recent ActivityRDoc 3.9.4 → 4.0.0RubyGems 1.8.24 → 2.0Rake 0.9.2.2 → 0.9.5 (Rake 10?)MiniTest 3.4.0 → 4.3.2空前のメジャーバージョンアップラッシュ
  • 11. Recent Activityかけこみコミットラッシュ
  • 12. New Featuresキーワード引数 Array#bsearchModule#prepend GC bitmap markingRefinement Debugger/ProfilerEnumerator::Lazy API スクリプトエンコーディングDTrace対応 UTF-8化TracePoint String#b
  • 13. Keyword Argumentsdef tupple(key: a , value: b ) { key => value }endtupple key: k , value: v # =>{ k => v }tupple value: 42 # => { a => 42 }tupple # => { a => b }
  • 14. Module#prepend obj C M Objectclass C; include M; endModule#include (Mixin) は定義済みのメソッドを上書きできない obj M C Objectclass C; prepend M; endModule#prepend は C のメソッドを上書きできるAround Alias (alias_method_chain) のかわりに使える
  • 15. Module#prependmodule Title def initialize(title, name) @title = title super(name) end def name @title + super endendclass Person def initialize(name) @name=name end def name @name end prepend TitleendPerson.new( Mr. , nagachika ).name #=> Mr.nagachika
  • 16. Module#prependprepend なしだと(include だと)class Person ...endmodule Title ...endclass Men < Person include Title def initialize super; @title = Mr. endend
  • 17. Refinement大幅路線変更?
  • 18. @a_matsuda++
  • 19. Enumerator::Lazy
  • 20. Enumerator::Lazy の前に
  • 21. Enumerable
  • 22. Enumerableもちろん使ってますよね?
  • 23. Array, Hash, IO...Array や Hash, IO は Enumerable を include している
  • 24. Enumerable【形容詞】 数えられる [日本語 WordNet(英和)) 可算;可付番 [クロスランゲージ 37分野専門語辞書]Capable of being enumerated;countable [Wikitionary]
  • 25. Enumerable「each メソッドを呼ぶと、何かが順に(N回) yield で渡される」というルール(N >= 0)
  • 26. Enumerableeach メソッドが定義されているクラスに include して使う(Mix-in)
  • 27. Enumerableeach だけ用意しておけばmap, select, reject, grep, etc...といったメソッドが使えるようになる(これらのメソッドが each を使って実装されている)
  • 28. An Exampleclass A include Enumerable def each yield 0 yield 1 yield 2 endendA.new.map{|i| i * 2 } # => [ 0, 2, 4 ]
  • 29. ここまでのまとめEnumerable は each メソッドを使って多彩なメソッドを追加するなにが「数え上げられる」のかはeach メソッドがどのようにyield を呼び出すかで決まる
  • 30. EnumeratorEnumerator使ってます?
  • 31. Enumeratoreach に渡すブロックを保留した状態でオブジェクトとして持ち回る
  • 32. to_enum, enum_forEnumerator の作りかた• Enumerator.new(obj, method=:each, *args)• obj.to_enum(method=:each, *args)• obj.enum_for(method=:each, *args)• Enumerator.new{|y| ...} ↑これだけちょっと特殊
  • 33. Object#enum_foreach 以外の任意のメソッドの呼び出しをEnumerator にできる(実は Enumerable でなくてもいい)e_byte = $stdin.enum_for(:each_byte) => バイトごとに yielde_line = $stdin.enum_for(:each_line) => 行ごとに yield
  • 34. Enumerator.new{|y|}e = Enumerator.new{|y| y << 0 y << :foo y << 2}ブロックが each の代わり。ブロックパラメータ y に << するとyield することになる。
  • 35. Enumerator.new{|y|}class A def each yield 0 yield :bar yield 2 endendA.new.to_enumと同じ
  • 36. Enumerator as External Iterator外部イテレータとして使えるe = (0..2).to_enume.next # => 0 each が yield する値がe.next # => 1 順に next で取り出せるe.next # => 2e.next=> StopIteration: iteration reached an end
  • 37. Method Chainmap, select など一部のメソッドはブロックを省略すると Enumerator を返すので複数のメソッドを組み合わせて使うary.map.with_index { |v,i| ... }
  • 38. Method Chain[:a, :b, :c, :d].map.with_index do |sym, i| i.even? ? sym : iend=> [:a, 1, :c, 3] Enumerator 独自のメソッド
  • 39. with_index[ruby-dev:31953] Matz wrote... mapがenumeratorを返すとobj.map.with_index{|x,i|....}ができるのが嬉しいので導入したのでした。というわけで、* eachにもmapにもwith_indexが付けられて嬉しいというのが本当の理由です。
  • 40. Secret Story of Enumerator. Enumerator はwith_index の為に 生まれた!
  • 41. ここまでのまとめ• Enumerator • 外部イテレータ化 • メソッドチェーン•
  • 42. Enumerator::Lazy2.0 の新機能
  • 43. Enumerator::LazyEnumeratorのサブクラス
  • 44. Enumerable#lazyEnumerator::Lazy の作りかたEnumerable#lazy を呼ぶ>> (0..5).lazy=> #<Enumerator::Lazy: 0..5>
  • 45. Enumerator::LazyLazyのmap,select,zipなど一部のメソッドがさらにLazyを返す>> (0..5).lazy.map{|i| i * 2}=> #<Enumerator::Lazy:#<Enumerator::Lazy: 0..5>:map>
  • 46. Enumerator::Lazy> Enumerator::Lazy.instance_methods(false) map collect flat_mapcollect_concat select find_all reject grep zip take take_while drop drop_wihle cycle lazy force [ruby 2.0.0dev (2012-05-30 trunk 35844)]
  • 47. forceEnumrator::Lazy#forceto_a の alias遅延されているイテレータの評価を実行
  • 48. A Lazy Demo>> l = (0..5).lazy=> <Enumerator::Lazy: 0..5>>> l_map = l.map{|i| p i; i * 2 }=> <Enumerator::Lazy: #<Enumerator::Lazy: 0..5>:map># この時点ではまだブロックの内容は実行されていない!>> l_map.force012345=> [0, 2, 4, 6, 8, 10]# force を呼ぶと実行される
  • 49. Enumeratorとの違いMethod Chain の使いかたがより強力に中間データの抑制
  • 50. Pitfall of Enumerator (1)map, select のようにブロックの戻り値を利用するメソッドを複数繋げることができない(しても意味がなくなる)(0..5).map.select{|i| i % 2 == 0 } => [ 0, 2, 4 ]↑ map の意味がなくなっている
  • 51. True Method Chainmap や select といったメソッドもいくつでもMethod Chain できる。そう、Lazy ならね。# 1 から 1000 のうち任意の桁に7を含む数を返す(1..1000).lazy.map(&:to_s).select{|s| /7/ =~ s}.force
  • 52. Pitfall of Enumerator (2)map, select のようにブロックの戻り値を利用するメソッドを外部イテレータ化しても意味がないe = (0..5).mape.next # => 0e.next # => 1e.next # => 2e.next # => 3↑ map の意味がなくなっている
  • 53. True External Iteratormap などにブロックを渡せるので適用した結果を順に取り出せるl = (0..5).lazy.select{|i| i.even? }l.next # => 0l.next # => 2l.next # => 4
  • 54. Efficient Memory UsageLazy は yield 毎に Method Chain の最後まで処理される
  • 55. Enumerable versionlarge_array.map{...}.select{...}
  • 56. Enumerable versionlarge_array.map{...}.select{...} map
  • 57. Enumerable versionlarge_array.map{...}.select{...} map select
  • 58. Enumerable versionlarge_array.map{...}.select{...} GCされる map select
  • 59. Enumerable versionlarge_array.map{...}.select{...} GCされる map select map 結果のためlarge_array と同じくらいの 中間データが必要
  • 60. Lazy versionlarge_array.lazy.map{...}.select{...}.force
  • 61. Lazy versionlarge_array.lazy.map{...}.select{...}.force
  • 62. Lazy versionlarge_array.lazy.map{...}.select{...}.force GC ed
  • 63. Lazy versionlarge_array.lazy.map{...}.select{...}.force
  • 64. Lazy versionlarge_array.lazy.map{...}.select{...}.force GC ed
  • 65. Lazy versionlarge_array.lazy.map{...}.select{...}.force
  • 66. Lazy versionlarge_array.lazy.map{...}.select{...}.force 中間データが不要
  • 67. Lazy Chain Demo>> (0..4).lazy.select{|i| p “select:#{i}”; i.event? }.map{|i| p “map:#{i}”; i * 2 }.force“select:0”“map:0”“select:1”“select:2”“map:2”“select:3”“select:4”“map:4”=> [0, 4, 8]
  • 68. Lazy with IO例) $stdin から空行を読むまでの各行の文字数の配列を返す$stdin.lazy.take_while{|l| ! l.chomp.empty?}.map {|l| l.chomp.size }
  • 69. Lazy with IOEnumerable, Enumerator だと空行まで先に読んでしまう。Lazy なら1行読むたびに take_while/mapのブロックが実行される → 逐次処理できる
  • 70. Lazy List無限に続く要素を扱えるlist = (0..Float::INFINITY)list.map{|i| i * 2}.take(5) => 返ってこないlist.lazy.map{|i| i * 2 }.take(5).force => [0, 2, 4, 6, 8]
  • 71. Interactivity実行順序を利用してインタラクティブに(0..Float::INFINITY).lazy.map{|i| p num line = $stdin.gets line.chomp if line}.take_while{|l| l and not l.empty?}.force
  • 72. Pitfall of Lazy?メモ化されない(force を2回呼ぶともう一度 each が呼ばれる) IOなど副作用のある each だと結果が 変化する ex) $stdin.lazy.take(1)enum_for のように each のかわりになるメソッドを指定できない $stdin.enum_for(:each_byte).lazy $stdin.lazy(:each_byte) と書きたい
  • 73. Lazy as a Better Enumerator Lazy は Enumerator の 正統進化版
  • 74. Happy LazyProgramming!

×