-
-
Save carld/0145c0d75caefef3741ce2f869ccac3a to your computer and use it in GitHub Desktop.
Lazy `#reduce` and `#join` in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "rspec/autorun" | |
class Enumerator::Lazy | |
def reduce(*) | |
Lazy.new([nil]) do |yielder, _| | |
yielder << super | |
end | |
end | |
def join(separator="") | |
reduce do |str, each| | |
"%s%s%s" % [str, separator, each] | |
end | |
end | |
end | |
RSpec.describe Enumerator::Lazy do | |
shared_examples_for "a lazy method" do | |
it "doesn't call its block" do | |
called = false | |
method.call do | |
called = true | |
end | |
expect(called).to be_falsy | |
end | |
end | |
subject { [1, 2, 3].lazy } | |
describe "#reduce" do | |
it_behaves_like "a lazy method" do | |
let(:method) { subject.public_method(:reduce) } | |
end | |
it "accepts the same number of arguments as Enumerable#reduce" do | |
enumerable = Object.new.extend(Enumerable).public_method(:reduce) | |
lazy = subject.public_method(:reduce) | |
expect(lazy.arity).to eq(enumerable.arity) | |
end | |
it "yields the result of calling reduce when forced" do | |
eager_sum = [1, 2, 3].reduce(0, :+) | |
lazy_sum = subject.reduce(0, :+) | |
expect(lazy_sum.first).to eq(eager_sum) | |
end | |
end | |
describe "#join" do | |
it_behaves_like "a lazy method" do | |
let(:method) { subject.public_method(:join) } | |
end | |
it "stringifies and joins values" do | |
expect(subject.join(",").first).to eq("1,2,3") | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment