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: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5d7d24a21b7d
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 9cf58de662cc
Choose a head ref
  • 4 commits
  • 3 files changed
  • 1 contributor

Commits on Jan 20, 2016

  1. Copy the full SHA
    f34954c View commit details

Commits on Jan 21, 2016

  1. Remove initial state from chunk

    jsyeo committed Jan 21, 2016
    Copy the full SHA
    7b81a46 View commit details
  2. Use a better error message

    jsyeo committed Jan 21, 2016
    Copy the full SHA
    b7c5d0d View commit details
  3. Merge pull request #3580 from jsyeo/jsyeo-slice_before

    Remove initial state from slice_before and chunk
    jsyeo committed Jan 21, 2016
    Copy the full SHA
    9cf58de View commit details
Showing with 19 additions and 63 deletions.
  1. +12 −18 kernel/common/enumerable.rb
  2. +5 −19 spec/ruby/core/enumerable/chunk_spec.rb
  3. +2 −26 spec/ruby/core/enumerable/slice_before_spec.rb
30 changes: 12 additions & 18 deletions kernel/common/enumerable.rb
Original file line number Diff line number Diff line change
@@ -4,19 +4,13 @@
# these methods can be written *in those classes* to override these.

module Enumerable
def chunk(initial_state = nil, &original_block)
def chunk
raise ArgumentError, "no block given" unless block_given?
::Enumerator.new do |yielder|
previous = nil
accumulate = []
block = if initial_state.nil?
original_block
else
duplicated_initial_state = initial_state.dup
Proc.new{ |val| original_block.yield(val, duplicated_initial_state)}
end
each do |element|
key = block.yield(element)
key = yield(element)
if key.nil? || (key.is_a?(Symbol) && key.to_s[0, 1] == "_")
yielder.yield [previous, accumulate] unless accumulate.empty?
accumulate = []
@@ -136,18 +130,18 @@ def group_by
h
end

def slice_before(arg = undefined, &block)
if block_given?
has_init = !(undefined.equal? arg)
else
raise ArgumentError, "wrong number of arguments (0 for 1)" if undefined.equal? arg
block = Proc.new{ |elem| arg === elem }
end
def slice_before(pattern = undefined, &block)
pattern_given = !(undefined.equal? pattern)

raise ArgumentError, "cannot pass both pattern and block" if pattern_given && block_given?
raise ArgumentError, "a pattern or a block must be provided" if !pattern_given && !block_given?

block = Proc.new{ |elem| pattern === elem } if pattern_given

Enumerator.new do |yielder|
init = arg.dup if has_init
accumulator = nil
each do |element|
start_new = has_init ? block.yield(element, init) : block.yield(element)
start_new = block.yield(element)
if start_new
yielder.yield accumulator if accumulator
accumulator = [element]
@@ -164,7 +158,7 @@ def slice_after(pattern = undefined, &block)
pattern_given = !undefined.equal?(pattern)

raise ArgumentError, "cannot pass both pattern and block" if pattern_given && block_given?
raise ArgumentError, "wrong number of arguments (0 for 1)" if !pattern_given && !block_given?
raise ArgumentError, "a pattern or a block must be provided" if !pattern_given && !block_given?

block = Proc.new { |elem| pattern === elem } if pattern_given

24 changes: 5 additions & 19 deletions spec/ruby/core/enumerable/chunk_spec.rb
Original file line number Diff line number Diff line change
@@ -12,6 +12,11 @@
end.should raise_error(ArgumentError)
end

it 'raises an ArgumentError if called with an argument' do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1)
lambda { e.chunk(42) { |x| x == 2 }.to_a }.should raise_error(ArgumentError)
end

it "returns an Enumerator if given a block" do
EnumerableSpecs::Numerous.new.chunk {}.should be_an_instance_of(enumerator_class)
end
@@ -51,25 +56,6 @@
lambda { e.chunk { |x| :_arbitrary }.to_a }.should raise_error(RuntimeError)
end

describe "with [initial_state]" do
it "yields an element and an object value-equal but not identical to the object passed to #chunk" do
e = EnumerableSpecs::Numerous.new(1)
value = "value"

e.chunk(value) do |x, v|
x.should == 1
v.should == value
v.should_not equal(value)
end.to_a
end

it "does not yield the object passed to #chunk if it is nil" do
e = EnumerableSpecs::Numerous.new(1)
e.chunk(nil) { |*x| ScratchPad << x }.to_a
ScratchPad.recorded.should == [[1]]
end
end

it 'returned Enumerator size returns nil' do
e = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 2, 1)
enum = e.chunk { |x| true }
28 changes: 2 additions & 26 deletions spec/ruby/core/enumerable/slice_before_spec.rb
Original file line number Diff line number Diff line change
@@ -41,32 +41,8 @@
end

describe "and an argument" do
it "calls the block with a copy of that argument" do
arg = [:foo]
first = nil
e = @enum.slice_before(arg) do |i, init|
init.should == arg
init.should_not equal(arg)
first = init
i == 6 || i == 2
end
e.should be_an_instance_of(enumerator_class)
e.to_a.should == [[7], [6, 5, 4, 3], [2, 1]]
e = @enum.slice_before(arg) do |i, init|
init.should_not equal(first)
end
e.to_a
end

quarantine! do # need to double-check with ruby-core. Might be wrong or too specific
it "duplicates the argument directly without calling dup" do
arg = EnumerableSpecs::Undupable.new
e = @enum.slice_before(arg) do |i, init|
init.initialize_dup_called.should be_true
false
end
e.to_a.should == [[7, 6, 5, 4, 3, 2, 1]]
end
it "raises an ArgumentError" do
lambda { @enum.slice_before("one") { |i| i == 6 } }.should raise_error(ArgumentError)
end
end
end