Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f29f3ec0a14e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ee48c162d504
Choose a head ref
  • 2 commits
  • 1 file changed
  • 2 contributors

Commits on Nov 6, 2014

  1. Copy the full SHA
    96ae48f View commit details
  2. Merge pull request #2121 from cheald/enum_slice

    Implement slice_after and slice_when
    enebo committed Nov 6, 2014
    Copy the full SHA
    ee48c16 View commit details
Showing with 67 additions and 13 deletions.
  1. +67 −13 core/src/main/ruby/jruby/kernel/enumerable.rb
80 changes: 67 additions & 13 deletions core/src/main/ruby/jruby/kernel/enumerable.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
module Enumerable
def slice_before(filter = (no_filter = true; nil), &block)
if no_filter && !block
raise ArgumentError.new("wrong number of arguments (0 for 1)")
end
raise ArgumentError.new("wrong number of arguments (0 for 1)") if no_filter && !block

if block
if no_filter
state = nil
else
initial_state = filter.dup
state = initial_state
end
else
state = nil
state = nil

if block && !no_filter
initial_state = filter.dup
state = initial_state
end

Enumerator.new do |yielder|
ary = nil
self.each do |*elt|
each do |*elt|
if elt.size < 2
elt = elt.size == 0 ? nil : elt[0]
end
@@ -47,6 +41,66 @@ def slice_before(filter = (no_filter = true; nil), &block)
end
end

def slice_after(filter = (no_filter = true; nil), &block)
raise ArgumentError.new("wrong number of arguments (0 for 1)") if no_filter && !block
raise ArgumentError.new("cannot pass both filter argument and block") if !no_filter && block

state = nil

Enumerator.new do |enum|
ary = []
each do |*element|
if element.size < 2
element = element.size == 0 ? nil : element[0]
end

if block
state = block.call element
else
state = (filter === element)
end

if state
ary << element
enum.yield ary
ary = []
else
ary << element
end
end
enum.yield ary unless ary.nil? || ary.empty?
end
end

def slice_when(&block)
raise ArgumentError.new("missing block") unless block
return Enumerator.new {|e| } if empty?
return Enumerator.new {|e| e.yield self } if length < 2

Enumerator.new do |enum|
ary = nil
last_after = nil
each_cons(2) do |before, after|
last_after = after
match = block.call before, after

ary ||= []
if match
ary << before
enum.yield ary
ary = []
else
ary << before
end
end

unless ary.nil?
ary << last_after
enum.yield ary
end
end
end

def lazy
klass = Enumerator::Lazy::LAZY_WITH_NO_BLOCK # Note: class_variable_get is private in 1.8
Enumerator::Lazy.new(klass.new(self, :each, []))