tottoruby 20130119

19
オフィスウーム 代表 坂口孝志 とっとるびー第11回 Ruby 2.0Enumerable#lazyとか

Upload: takashi-sakaguchi

Post on 12-Jun-2015

598 views

Category:

Technology


6 download

DESCRIPTION

第11回とっとるびー発表 Enumerable#lazyがデフォだとまずい点⇒副作用があると少し面倒なことになりそう。

TRANSCRIPT

Page 1: Tottoruby 20130119

オフィスウーム 代表

坂口孝志

とっとるびー第11回

Ruby 2.0のEnumerable#lazyとか

Page 2: Tottoruby 20130119

自己紹介● 鳥取の技術者集団 オフィス ウーム

● 代表やってます● 集団だけど現在は一人です● 一応年内には法人化予定です

– http://www.ummm.info– 法人化次第、co.jpに変更する予定

● 並行して某企業に勤務、1月末で退職予定● ここ数年、わりとRuby

Page 3: Tottoruby 20130119

陳謝と駄文● 独立したよって言いたかっただけです。● 発表はついでです。

● ついでだけど、頑張るつもりでした。● だけどぶっちゃけ時間が取れませんでした。● (´・ω・`)

● MacBook Air買いました。● フォントが綺麗で失禁寸前でした。● まっくかわいいよまっく● ターミナルとGUIがシームレスなことにマジ感動● それでも、無料でメールホスティングしてくれる太っ腹のMicrosoft

さんが大好きです。

Page 4: Tottoruby 20130119

今回の発表について● やる内容

● Ruby2.0の新機能(Enumerable#lazy)咀嚼● かつ、その前提知識のおさらい

● 想定レベル● Rubyのproc, lambdaがなんとなく読める

Page 5: Tottoruby 20130119

アジェンダ● Enumerableモジュールについて触っとく

● Enumerable#lazyについて● Enumerable#lazyとは何か?● 用例その1● 用例その2

Page 6: Tottoruby 20130119

アジェンダ● Enumerableモジュールについて触っとく

● Enumerable#lazyについて● Enumerable#lazyとは何か?● 用例その1● 用例その2

Page 7: Tottoruby 20130119

Enumerableモジュール● モジュール

● クラスに#eachが定義されている前提で動作するメソッド群

● 順々に何かを数え上げるような動作を期待class Hoge def each yield 1; yield 2; yield 3 endendHoge.send(:include, Enumerable)

h = Hoge.newputs h.map { |x| x*2 }

Page 8: Tottoruby 20130119

Enumerable – 1.9からのお約束● #eachにブロックを渡さない場合の挙動

● Enumeratorクラスのインスタンスを返すclass Hoge def each &block Enumerator.new do |y| y << 1; y << 2; y << 3 end.each(&block) endendHoge.send(:include, Enumerable)

h = Hoge.newe = h.mapputs e.map { |x| x*2 }

Page 9: Tottoruby 20130119

それって、何が良い感じなの?● #eachって名称のメソッド以外にも

Enumerableなメソッド群の適用が容易に

puts open(__FILE__, 'rb').each_line.map { |line| line.size}.max

#each_lineに対して#mapを適用している

Page 10: Tottoruby 20130119

アジェンダ● Enumerableモジュールについて触っとく

● Enumerable#lazyについて● Enumerable#lazyとは何か?● 用例その1● 用例その2

Page 11: Tottoruby 20130119

アジェンダ● Enumerableモジュールについて触っとく

● Enumerable#lazyについて● Enumerable#lazyとは何か?● 用例その1● 用例その2

Page 12: Tottoruby 20130119

Enumerable#lazyとは何か?● Enumerableのインスタンスメソッド

● Enumerator::Lazyのインスタンスを返す↑こいつが本題

● Enumerator::Lazyとは● Enumeratorのサブクラスで、

いくつかのメソッドの挙動を置き換えてる。– #map, #collect, #flat_map,

#collect_concat, #select, #size, #find_all, #reject, #grep, #zip, #take, #take_while, #drop, #drop_while, #cycle, #lazy, #force

Page 13: Tottoruby 20130119

Enumerator::Lazyとは何か?● とどのつまり、遅延評価。

● 評価してみたけど、実は必要ではなかったってことはよくある。– そんな時は処理しない。

0

1

2

3

4

5

6

7

8

9

0

3

6

9

“0”

“3”

“6”

“9”

X%3==0 to_s

否Lazy 否Lazy

lazylazy

lazy

Page 14: Tottoruby 20130119

アジェンダ● Enumerableモジュールについて触っとく

● Enumerable#lazyについて● Enumerable#lazyとは何か?● 用例その1● 用例その2

Page 15: Tottoruby 20130119

用例その1ー超大きなデータ● ファイル中を読んでマスクして出力

# ファイル中の、とても30代の大人が# 発するとは思えない単語をカウントする# lazyがあればGB超のファイルでも1行ずつ処理するから安心count = STDIN.each_line.lazy.map do |l| l.split.count { |w| w == 'unko' }end.inject(&:+)

puts count

Page 16: Tottoruby 20130119

アジェンダ● Enumerableモジュールについて触っとく

● Enumerable#lazyについて● Enumerable#lazyとは何か?● 用例その1● 用例その2

Page 17: Tottoruby 20130119

用例その2ー無限が容易に扱える● 無限に続く要素にEnumerableな操作ができる

require 'prime'

# 素数の中で、1の位が1の数値を10個得るputs Prime.lazy.select { |x| (x % 10) == 1 }.first(10)

# 以下は終了しない# puts Prime.select { |x| (x % 10) == 1 }.first(10)

Page 18: Tottoruby 20130119

まとめ● Enumerableモジュール便利

● #eachを定義しとくだけで色々できる● Template Method的な● 集合演算的な● 意識せずとも、みんないつの間にか使ってる

● Enumerable#lazyはEnumerator::Lazyを作る● いくつかのメソッドをオーバーライド、評価を遅延する。● 本当に必要なものを必要なタイミングで得る● Enumeratorの挙動がデフォでLazyな挙動でもいい気がする。– ダメな理由あるの?

Page 19: Tottoruby 20130119

おわり

父にかわってお詫び申し上げます