Last active
August 29, 2015 14:08
-
-
Save eriktrom/da7846c5c3a92ed038fe to your computer and use it in GitHub Desktop.
Ruby Enumerable Iterators
This file contains hidden or 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 'active_support/core_ext/string' | |
RSpec.describe 'Ruby Enumerator Examples' do | |
def ext_each(enum) | |
while true | |
begin | |
values = enum.next_values | |
rescue StopIteration => err | |
return err.result | |
end | |
y = yield(*values) | |
enum.feed y | |
end | |
end | |
obj = Object.new | |
def obj.each &block | |
yield 0 | |
yield 1 | |
yield 1,2 | |
3 | |
end | |
describe 'using obj.each as an internal iterator' do | |
it 'should work via stdout' do | |
stdout_expected = <<-HEREDOC.strip_heredoc | |
oh hai! [0] | |
["blah", 0]oh hai! [1] | |
["blah", 1]oh hai! [1, 2] | |
["blah", 1, 2]3 | |
HEREDOC | |
expect { | |
puts obj.each {|*x| print(puts "oh hai! #{x}"); print(['blah', *x]) } | |
}.to output(stdout_expected).to_stdout | |
end | |
it 'works but is ugly using rspec block matchers' do | |
def wow_probe_it obj | |
yield obj.each {|*x| yield "oh hai! #{x}"; yield ['blah', *x] } | |
end | |
expected = [ | |
"oh hai! [0]", | |
["blah", 0], "oh hai! [1]", | |
["blah", 1], "oh hai! [1, 2]", | |
["blah", 1, 2], | |
3 | |
] | |
expect {|probe| wow_probe_it(obj, &probe) }.to yield_successive_args(*expected) | |
end | |
end | |
describe 'using obj.each as an external iterator' do | |
it 'should work via stdout' do | |
stdout_expected = <<-HEREDOC.strip_heredoc | |
oh hai! [0] | |
["blah", 0]oh hai! [1] | |
["blah", 1]oh hai! [1, 2] | |
["blah", 1, 2]3 | |
HEREDOC | |
expect { | |
# variant that makes it an external iterator: ext_each(obj.to_enum) | |
puts ext_each(obj.to_enum) {|*x| print(puts "oh hai! #{x}"); print(['blah', *x]) } | |
}.to output(stdout_expected).to_stdout | |
end | |
it 'works but is ugly using rspec block matchers' do | |
def wow_probe_it obj | |
# variant that makes it an external iterator: ext_each(obj.to_enum) | |
yield ext_each(obj.to_enum) {|*x| yield "oh hai! #{x}"; yield ['blah', *x] } | |
end | |
expected = [ | |
"oh hai! [0]", | |
["blah", 0], "oh hai! [1]", | |
["blah", 1], "oh hai! [1, 2]", | |
["blah", 1, 2], | |
3 | |
] | |
expect {|probe| wow_probe_it(obj, &probe) }.to yield_successive_args(*expected) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment