Skip to content

Commit

Permalink
Fix JRUBY-6892: Calling #drop on an Enumerator doesn't work properly
Browse files Browse the repository at this point in the history
When "drop" is called on an Enumerator, the memory locations for the members of the return value were reused.
This resulted in a wrong result that the ticket describes. We address the problem by calling dup() whenever appropriate.
  • Loading branch information
BanzaiMan committed Sep 16, 2012
1 parent f125aeb commit d991aba
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
10 changes: 10 additions & 0 deletions spec/regression/JRUBY-6892_drop_on_enumerator_oddity_spec.rb
@@ -0,0 +1,10 @@
require 'rspec'

describe "Enumerable#drop" do
context "when called on an Enumerator" do
let(:enumerator) { (1..10).to_a.each_slice(3)}
it "should behave as if it is called on an Enumerable" do
enumerator.drop(2).should == [[7,8,9],[10]]
end
end
end
5 changes: 4 additions & 1 deletion src/org/jruby/RubyEnumerable.java
Expand Up @@ -280,7 +280,10 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
IRubyObject larg = checkArgs(runtime, largs);
synchronized (result) {
if (i == 0) {
result.append(larg);
// While iterating over an RubyEnumerator, "arg"
// gets overwritten by the new value, leading to JRUBY-6892.
// So call .dup() whenever appropriate.
result.append(larg.isImmediate() ? larg : larg.dup());
} else {
--i;
}
Expand Down

0 comments on commit d991aba

Please sign in to comment.