听惰性可枚举

Listen to lazy enumerable

我正在尝试构建可以处理事件流的东西。我希望我的处理器没有副作用,因此它们易于管理,但我也想确保我不会 运行 通过流两次。

class A
  def initialize(*processors)
    @processors = processors
  end
  def call(list)
    @processors.inject(0) { |acc, p|
      acc + p.call(list)
    }
  end
end

class B
  def initialize(multiplier)
    @multiplier = multiplier
  end

  def call(list)
    list.map { |i|
      i * @multiplier
    }.inject(0) { |acc, i|
      puts "B with multipler: #{@multiplier}, adding: #{i}"
      acc + i
    }
  end
end

A.new(B.new(1), B.new(2)).call([1, 2, 3, 4, 5].lazy)
# => 45

Class A 完全错误,因为执行顺序是:

# B with multipler: 1, adding: 1
# B with multipler: 1, adding: 2
# B with multipler: 1, adding: 3
# B with multipler: 1, adding: 4
# B with multipler: 1, adding: 5
# B with multipler: 2, adding: 2
# B with multipler: 2, adding: 4
# B with multipler: 2, adding: 6
# B with multipler: 2, adding: 8
# B with multipler: 2, adding: 10

我如何修改 class A 来给我一个执行顺序:

# B with multipler: 1, adding: 1
# B with multipler: 2, adding: 2
# B with multipler: 1, adding: 2
# B with multipler: 2, adding: 4
# B with multipler: 1, adding: 3
# B with multipler: 2, adding: 6
# B with multipler: 1, adding: 4
# B with multipler: 2, adding: 8
# B with multipler: 1, adding: 5
# B with multipler: 2, adding: 10

我需要某种更复杂的可枚举类型吗?

如果您想将处理器应用于值,以便您需要一次发送一个

class A
  def initialize(*processors)
    @processors = processors
  end
  def call(list)
    list.inject(0) do |acc, item|
      acc + @processors.map { |processor| processor.call(item) }.inject(:+)
    end
  end
end

class B
  def initialize(multiplier)
    @multiplier = multiplier
  end

  def call(item)
    puts "B with multipler: #{@multiplier}, adding: #{item}"
    item * @multiplier
  end
end

p A.new(B.new(1), B.new(2)).call([1, 2, 3, 4, 5].lazy)