狠狠撸

狠狠撸Share a Scribd company logo
とっとるびー第11回



Ruby 2.0のEnumerable#lazyとか



                  オフィスウーム 代表
                        坂口孝志
自己紹介
●
    鳥取の技術者集団 オフィス ウーム
    ●
        代表やってます
    ●
        集団だけど現在は一人です
    ●
        一応年内には法人化予定です
        – http://www.ummm.info
        – 法人化次第、co.jpに変更する予定


●
    並行して某企業に勤務、1月末で退職予定
    ●
        ここ数年、わりとRuby
陳謝と駄文
●
    独立したよって言いたかっただけです。
●
    発表はついでです。
    ●
        ついでだけど、頑張るつもりでした。
    ●
        だけどぶっちゃけ時間が取れませんでした。
    ●
        (??ω?`)
●
    MacBook Air買いました。
    ●
        フォントが綺麗で失禁寸前でした。
    ●
        まっくかわいいよまっく
    ●
        ターミナルとGUIがシームレスなことにマジ感動
    ●
        それでも、無料でメールホスティングしてくれる太っ腹のMicrosoft
        さんが大好きです。
今回の発表について
●
    やる内容
    ●
        Ruby2.0の新機能(Enumerable#lazy)咀嚼
    ●
        かつ、その前提知識のおさらい

●
    想定レベル
    ●
        Rubyのproc, lambdaがなんとなく読める
アジェンダ
●
    Enumerableモジュールについて触っとく


●
    Enumerable#lazyについて
    ●
        Enumerable#lazyとは何か?
    ●
        用例その1
    ●
        用例その2
アジェンダ
●
    Enumerableモジュールについて触っとく


●
    Enumerable#lazyについて
    ●
        Enumerable#lazyとは何か?
    ●
        用例その1
    ●
        用例その2
Enumerableモジュール
●
    モジュール
    ●
        クラスに#eachが
        定義されている前提で動作するメソッド群
    ●
        順々に何かを数え上げるような動作を期待
               class Hoge
                def each
                  yield 1; yield 2; yield 3
                end
               end
               Hoge.send(:include, Enumerable)

               h = Hoge.new
               puts h.map { |x| x*2 }
Enumerable – 1.9からのお約束
●
    #eachにブロックを渡さない場合の挙動
    ●
        Enumeratorクラスのインスタンスを返す
         class Hoge
          def each &block
            Enumerator.new do |y|
             y << 1; y << 2; y << 3
            end.each(&block)
          end
         end
         Hoge.send(:include, Enumerable)

         h = Hoge.new
         e = h.map
         puts e.map { |x| x*2 }
それって、何が良い感じなの?
●
    #eachって名称のメソッド以外にも
    Enumerableなメソッド群の適用が容易に


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




                              #each_lineに対して
                             #mapを適用している
アジェンダ
●
    Enumerableモジュールについて触っとく


●
    Enumerable#lazyについて
    ●
        Enumerable#lazyとは何か?
    ●
        用例その1
    ●
        用例その2
アジェンダ
●
    Enumerableモジュールについて触っとく


●
    Enumerable#lazyについて
    ●
        Enumerable#lazyとは何か?
    ●
        用例その1
    ●
        用例その2
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
Enumerator::Lazyとは何か?
●
    とどのつまり、遅延評価。
    ●
        評価してみたけど、
        実は必要ではなかったってことはよくある。
        –   そんな時は処理しない。
            0   X%3==0       0   to_s     “0”
                         lazy
            1
                         lazy
            2
                         lazy
            3                3            “3”
            4
            5    否Lazy            否Lazy
            6               6             “6”
            7
            8
            9               9             “9”
アジェンダ
●
    Enumerableモジュールについて触っとく


●
    Enumerable#lazyについて
    ●
        Enumerable#lazyとは何か?
    ●
        用例その1
    ●
        用例その2
用例その1ー超大きなデータ
●   ファイル中を読んでマスクして出力

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

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


●
    Enumerable#lazyについて
    ●
        Enumerable#lazyとは何か?
    ●
        用例その1
    ●
        用例その2
用例その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)
まとめ
●
    Enumerableモジュール便利
    ●
        #eachを定義しとくだけで色々できる
    ●
        Template Method的な
    ●
        集合演算的な
    ●
        意識せずとも、みんないつの間にか使ってる

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



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

More Related Content

Tottoruby 20130119

  • 1. とっとるびー第11回 Ruby 2.0のEnumerable#lazyとか オフィスウーム 代表 坂口孝志
  • 2. 自己紹介 ● 鳥取の技術者集団 オフィス ウーム ● 代表やってます ● 集団だけど現在は一人です ● 一応年内には法人化予定です – http://www.ummm.info – 法人化次第、co.jpに変更する予定 ● 並行して某企業に勤務、1月末で退職予定 ● ここ数年、わりとRuby
  • 3. 陳謝と駄文 ● 独立したよって言いたかっただけです。 ● 発表はついでです。 ● ついでだけど、頑張るつもりでした。 ● だけどぶっちゃけ時間が取れませんでした。 ● (??ω?`) ● MacBook Air買いました。 ● フォントが綺麗で失禁寸前でした。 ● まっくかわいいよまっく ● ターミナルとGUIがシームレスなことにマジ感動 ● それでも、無料でメールホスティングしてくれる太っ腹のMicrosoft さんが大好きです。
  • 4. 今回の発表について ● やる内容 ● Ruby2.0の新機能(Enumerable#lazy)咀嚼 ● かつ、その前提知識のおさらい ● 想定レベル ● Rubyのproc, lambdaがなんとなく読める
  • 5. アジェンダ ● Enumerableモジュールについて触っとく ● Enumerable#lazyについて ● Enumerable#lazyとは何か? ● 用例その1 ● 用例その2
  • 6. アジェンダ ● Enumerableモジュールについて触っとく ● Enumerable#lazyについて ● Enumerable#lazyとは何か? ● 用例その1 ● 用例その2
  • 7. Enumerableモジュール ● モジュール ● クラスに#eachが 定義されている前提で動作するメソッド群 ● 順々に何かを数え上げるような動作を期待 class Hoge def each yield 1; yield 2; yield 3 end end Hoge.send(:include, Enumerable) h = Hoge.new puts h.map { |x| x*2 }
  • 8. Enumerable – 1.9からのお約束 ● #eachにブロックを渡さない場合の挙動 ● Enumeratorクラスのインスタンスを返す class Hoge def each &block Enumerator.new do |y| y << 1; y << 2; y << 3 end.each(&block) end end Hoge.send(:include, Enumerable) h = Hoge.new e = h.map puts e.map { |x| x*2 }
  • 9. それって、何が良い感じなの? ● #eachって名称のメソッド以外にも Enumerableなメソッド群の適用が容易に puts open(__FILE__, 'rb').each_line.map { |line| line.size }.max #each_lineに対して #mapを適用している
  • 10. アジェンダ ● Enumerableモジュールについて触っとく ● Enumerable#lazyについて ● Enumerable#lazyとは何か? ● 用例その1 ● 用例その2
  • 11. アジェンダ ● Enumerableモジュールについて触っとく ● Enumerable#lazyについて ● Enumerable#lazyとは何か? ● 用例その1 ● 用例その2
  • 12. 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
  • 13. Enumerator::Lazyとは何か? ● とどのつまり、遅延評価。 ● 評価してみたけど、 実は必要ではなかったってことはよくある。 – そんな時は処理しない。 0 X%3==0 0 to_s “0” lazy 1 lazy 2 lazy 3 3 “3” 4 5 否Lazy 否Lazy 6 6 “6” 7 8 9 9 “9”
  • 14. アジェンダ ● Enumerableモジュールについて触っとく ● Enumerable#lazyについて ● Enumerable#lazyとは何か? ● 用例その1 ● 用例その2
  • 15. 用例その1ー超大きなデータ ● ファイル中を読んでマスクして出力 # ファイル中の、とても30代の大人が # 発するとは思えない単語をカウントする # lazyがあればGB超のファイルでも1行ずつ処理するから安心 count = STDIN.each_line.lazy.map do |l| l.split.count { |w| w == 'unko' } end.inject(&:+) puts count
  • 16. アジェンダ ● Enumerableモジュールについて触っとく ● Enumerable#lazyについて ● Enumerable#lazyとは何か? ● 用例その1 ● 用例その2
  • 17. 用例その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)
  • 18. まとめ ● Enumerableモジュール便利 ● #eachを定義しとくだけで色々できる ● Template Method的な ● 集合演算的な ● 意識せずとも、みんないつの間にか使ってる ● Enumerable#lazyはEnumerator::Lazyを作る ● いくつかのメソッドをオーバーライド、評価を遅延する。 ● 本当に必要なものを必要なタイミングで得る ● Enumeratorの挙動が デフォでLazyな挙動でもいい気がする。 – ダメな理由あるの?
  • 19. おわり 父にかわって お詫び申し上げます