Enumerator vs Enumerable

  1. На първата лекция за 2017-та ще говорим за Enumerator. Основните разлики са:

    • Enumerable е модул. За да го ползваш имплементираш each и го инклудваш. Идеята му е "аз съм нещо итерируемо, дай ми методите за итериране"
    class CookieFactory
      # ...
    
      include Enumerable
    
      def each
        while cookies_to_bake?
          yield bake_cookie
        end
      end
    end
    
    CookieFactory.new.map { |cookie| add_chocolate_to(cookie) }
    
    • Enumerator е клас. Той не е направен за наследяване, а за директно използване. Идеята му е "Имам нещо за итериране - ето ти го - ти се грижѝ за итерирането".
    class CookieFactory
      # ...
    
      def cookies
        while cookies_to_bake?
          yield bake_cookie
        end
      end
    end
    
    Enumerator.new(CookieFactory.new, :cookies).map { |cookie| add_chocolate_to(cookie) }
    
    # Това е еквивалентно на горното и за предпочитане:
    CookieFactory.new.to_enum(:cookies).map { |cookie| add_chocolate_to(cookie) }
    

    Enumerator дава повече контрол:

    class CookieFactory
      # ...
    
      def cookies(color)
        while cookies_to_bake?
          yield bake_colorful_cookie(color)
        end
      end
    end
    
    # `to_enum` ще предаде параметъра на метода `cookies`. По този начин можем да
    # параметризираме итерираните неща, за разлика от Enumerable, където не можем да
    # предадем параметри на `each`.
    cookie_factory = CookieFactory.new
    cookie_factory.to_enum(:cookies, 'red').map { |red_cookie| add_chocolate_to(red_cookie) }
    cookie_factory.to_enum(:cookies, 'blue').map { |blue_cookie| add_chocolate_to(blue_cookie) }
    

    Виж този пост и този пост

    ПП. Enumerator имплементира Enumerable :) ПП2. Може да се използва за безкрайни потоци и мързеливи операции

Трябва да сте влезли в системата, за да може да отговаряте на теми.