Class: Enumerator

Inherits:
Object show all
Defined in:
lib/epitools/core_ext/enumerable.rb

Constant Summary collapse

SPINNER =
['-', '\\', '|', '/']

Instance Method Summary collapse

Instance Method Details

#*(other) ⇒ Object

Multiplies this Enumerator by something else.

Enumerator * Integer == a new Enumerator that repeats the original one <Integer> times Enumerator * String == joins the Enumerator’s elements into a new string, with <String> in between each pair of elements Enumerator * Enumerable == the cross product (aka. cartesian product) of the Enumerator and the Enumerable



621
622
623
624
625
626
627
628
629
630
631
632
# File 'lib/epitools/core_ext/enumerable.rb', line 621

def *(other)
  case other
  when Integer
    cycle(other)
  when String
    join(other)
  when Enumerable
    cross(other)
  else
    raise "#{other.class} is not something that can be multiplied by an Enumerator"
  end
end

#+(other) ⇒ Object

Concatenates two Enumerators, returning a new Enumerator.



604
605
606
607
608
609
610
611
# File 'lib/epitools/core_ext/enumerable.rb', line 604

def +(other)
  raise "Can only concatenate Enumerable things to Enumerators" unless Enumerable === other

  Enumerator.new(count + other.count) do |yielder|
    each { |e| yielder << e }
    other.each { |e| yielder << e }
  end
end

#cross_product(other) ⇒ Object Also known as: cross

Takes the cross product (aka. cartesian product) of the Enumerator and the argument, returning a new Enumerator. (The argument must be some kind of Enumerable.)



638
639
640
641
642
# File 'lib/epitools/core_ext/enumerable.rb', line 638

def cross_product(other)
  Enumerator.new(count + other.count) do |yielder|
    each { |a| other.each { |b| yielder << [a,b] } }
  end
end

#values_at(*indexes) ⇒ Object

Pass in a bunch of indexes to elements in the Enumerator, and this method lazily returns them as a new Enumerator.



584
585
586
587
588
589
590
591
592
593
594
595
596
597
# File 'lib/epitools/core_ext/enumerable.rb', line 584

def values_at(*indexes)
  return if indexes.empty?

  indexes.flatten!

  indexes = Set.new(indexes)

  Enumerator.new do |yielder|
    each_with_index do |e,i|
      yielder << e if indexes.delete(i)
      break if indexes.empty?
    end
  end
end

#with_spinner(every = 37) ⇒ Object

Display a spinner every ‘every` elements that pass through the Enumerator.



560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
# File 'lib/epitools/core_ext/enumerable.rb', line 560

def with_spinner(every=37)
  to_enum do |yielder|
    spins = 0

    each.with_index do |e, i|
      if i % every == 0
        print "\b" unless spins == 0
        print SPINNER[spins % 4]

        spins += 1
      end

      yielder << e
    end

    print "\b \b" # erase the spinner when done
  end
end