Skip to content

Instantly share code, notes, and snippets.

@eriktrom
Last active August 29, 2015 14:08
Show Gist options
  • Save eriktrom/da7846c5c3a92ed038fe to your computer and use it in GitHub Desktop.
Save eriktrom/da7846c5c3a92ed038fe to your computer and use it in GitHub Desktop.
Ruby Enumerable Iterators
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