Created
August 7, 2015 10:44
-
-
Save sharplet/2d153baf938ac528b67a 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