Skip to content

Instantly share code, notes, and snippets.

@avdi
Last active August 29, 2015 14:10
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avdi/20037a488409dd2d7df1 to your computer and use it in GitHub Desktop.
Save avdi/20037a488409dd2d7df1 to your computer and use it in GitHub Desktop.
module Enumerable
def each_with_emptiness
return to_enum(__callee__) unless block_given?
if empty?
yield nil, true
else
each do |element|
yield element, false
end
end
end
end
[].each_with_emptiness do |n, empty|
break puts "None found" if empty
puts "Number: #{n}"
end
# >> None found
@ReneB
Copy link

ReneB commented Nov 28, 2014

I like it, but I have a couple of questions (which may go beyond the original intention of the gist, in which case, sorry to bother you).

First off, I think this also begs for a .with_emptiness method on Enumerator, since all each_with_x methods I know of (which is, admittedly, only 2: each_with_object and each_with_index) are also available als each.with_x

And would it, then, help to implement this as something like this, or am I missing some subtleties (aside from the fact that this kind of methods on Enumerator is usually implemented in C)?

module Enumerable
  def each_with_emptiness(&block)
    each.with_emptiness(&block)
  end
end

class Enumerator
  def with_emptiness
    return to_enum(__callee__) unless block_given?

    begin
      peek

      each do |element|
        yield element, false
      end
    rescue StopIteration
      yield nil, true
    end
  end
end

[].each_with_emptiness do |n, empty|
  break puts "None found" if empty
  puts "Number: #{n}"
end

@drbrain
Copy link

drbrain commented Dec 1, 2014

@ReneB I think the use of peek and StopIteration is a nice update as Enumerator does not require a #empty?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment