Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: EPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Eclipse Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/epl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyright (C) 2006 Ola Bini <ola@ologix.com> Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the EPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the EPL, the GPL or the LGPL. END LICENSE BLOCK ***
  
  package org.jruby;
  
  
  import java.util.Arrays;
  import java.util.List;
  
  import static org.jruby.CompatVersion.RUBY1_8;
  import static org.jruby.CompatVersion.RUBY1_9;
  import static org.jruby.RubyEnumerator.enumeratorize;
  import static org.jruby.runtime.Helpers.invokedynamic;
  import static org.jruby.runtime.invokedynamic.MethodNames.OP_CMP;

The implementation of Ruby's Enumerable module.
  
  
  @JRubyModule(name="Enumerable")
  public class RubyEnumerable {
  
      public static RubyModule createEnumerableModule(Ruby runtime) {
          RubyModule enumModule = runtime.defineModule("Enumerable");
          runtime.setEnumerable(enumModule);
          
          enumModule.defineAnnotatedMethods(RubyEnumerable.class);
  
          return enumModule;
      }
  
      public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject self,
              BlockCallback callback) {
          return Helpers.invoke(contextself"each", CallBlock.newCallClosure(selfruntime.getEnumerable(),
                  .callbackcontext));
      }
  
      public static IRubyObject callEach19(Ruby runtimeThreadContext contextIRubyObject self,
              BlockCallback callback) {
          return Helpers.invoke(contextself"each", CallBlock19.newCallClosure(selfruntime.getEnumerable(),
                  .callbackcontext));
      }
  
      @Deprecated
      public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject selfIRubyObject[] args,
              BlockCallback callback) {
          return Helpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(), .callbackcontext));
      }
  
      public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject self,
              Arity arityBlockCallback callback) {
          return Helpers.invoke(contextself"each", CallBlock.newCallClosure(selfruntime.getEnumerable(),
                  aritycallbackcontext));
      }
  
     public static IRubyObject callEach19(Ruby runtimeThreadContext contextIRubyObject self,
             Arity arityBlockCallback callback) {
         return Helpers.invoke(contextself"each", CallBlock19.newCallClosure(selfruntime.getEnumerable(),
                 aritycallbackcontext));
     }
     
     public static IRubyObject each(ThreadContext contextIRubyObject selfBlockBody body) {
         Block block = new Block(bodycontext.currentBinding(self.));
         return Helpers.invoke(contextself"each"block);
     }
 
     @Deprecated
     public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject selfIRubyObject[] args,
             Arity arityBlockCallback callback) {
         return Helpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(), aritycallbackcontext));
     }
 
     private static void checkContext(ThreadContext firstContextThreadContext secondContextString name) {
         if (firstContext != secondContext) {
             throw secondContext.runtime.newThreadError("Enumerable#" + name + " cannot be parallelized");
         }
     }
 
     @JRubyMethod(name = "count", compat = .)
     public static IRubyObject count18(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven() && self.respondsTo("size")) {
             return self.callMethod(context"size");
         }
 
         return countCommon(contextselfblock.);
     }
 
     @JRubyMethod(name = "count", compat = .)
     public static IRubyObject count(ThreadContext contextIRubyObject selffinal Block block) {
         return countCommon(contextselfblockblock.arity());
     }
 
     private static IRubyObject countCommon(ThreadContext contextIRubyObject selffinal Block blockArity callbackArity) {
         final Ruby runtime = context.runtime;
         final int result[] = new int[] { 0 };
         
         if (block.isGiven()) {
             callEach(runtimecontextselfcallbackAritynew BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject packedArgs = packEnumValues(ctx.runtimelargs);
                     if (block.yield(ctxpackedArgs).isTrue()) result[0]++;
                     return runtime.getNil();
                 }
             });
         } else {
             each(contextselfnew JavaInternalBlockBody(runtimecontext"Enumerable#count".) {
                 public IRubyObject yield(ThreadContext contextIRubyObject unusedValue) {
                     result[0]++;
                     return runtime.getNil();
                 }
             });
         }
         return RubyFixnum.newFixnum(runtimeresult[0]);
     }
 
     @JRubyMethod(name = "count", compat = .)
     public static IRubyObject count18(ThreadContext contextIRubyObject selffinal IRubyObject methodArgfinal Block block) {
         return count(contextselfmethodArgblock);
     }
 
     @JRubyMethod(name = "count", compat = .)
     public static IRubyObject count(ThreadContext contextIRubyObject selffinal IRubyObject methodArgfinal Block block) {
         final Ruby runtime = context.runtime;
         final int result[] = new int[] { 0 };
         
         if (block.isGiven()) runtime.getWarnings().warn(. , "given block not used");
         
         each(contextselfnew JavaInternalBlockBody(runtimecontext"Enumerable#count".) {
             public IRubyObject yield(ThreadContext contextIRubyObject blockArg) {
                 if (blockArg.equals(methodArg)) result[0]++;
                 
                 return runtime.getNil();
             }
         });
 
         return RubyFixnum.newFixnum(runtimeresult[0]);
     }
     
     @JRubyMethod
     public static IRubyObject cycle(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"cycle");
         }
         
         return cycleCommon(contextself, -1, block);
     }
 
     @JRubyMethod
     public static IRubyObject cycle(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
         if (arg.isNil()) return cycle(contextselfblock);
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"cycle"arg);
         }
 
         long times = RubyNumeric.num2long(arg);
         if (times <= 0) {
             return context.runtime.getNil();
         }
 
         return cycleCommon(contextselftimesblock);
     }
 
     /*
      * @param nv number of times to cycle or -1 to cycle indefinitely
      */
     private static IRubyObject cycleCommon(ThreadContext contextIRubyObject selflong nvfinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         each(contextselfnew JavaInternalBlockBody(runtime.) {
             public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                 synchronized (result) { result.append(arg); }
                 block.yield(contextarg);
                 return runtime.getNil();            
             }
         });
 
         int length = result.size();
         if (length == 0) return runtime.getNil();
 
         while (nv < 0 || 0 < --nv) {
             for (int i=0; i < lengthi++) {
                 block.yield(contextresult.eltInternal(i));
             }
         }
 
         return runtime.getNil();
     }
 
     @JRubyMethod(name = "take")
     public static IRubyObject take(ThreadContext contextIRubyObject selfIRubyObject nBlock block) {
         final Ruby runtime = context.runtime;
         final long len = RubyNumeric.num2long(n);
         
         if (len < 0) throw runtime.newArgumentError("attempt to take negative size");
         if (len == 0) return runtime.newEmptyArray();
 
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(runtime.) {
                 long i = len// Atomic ?
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     synchronized (result) {
                         result.append(arg);
                         if (-- == 0) throw .
                     }
                     
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump e) {}
         
         return result;
     }
 
     @JRubyMethod(name = "take_while", compat = )
     public static IRubyObject take_while18(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"take_while");
         }
 
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(runtime.) {
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     if (!block.yield(contextarg).isTrue()) throw .;
                     synchronized (result) { result.append(arg); }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
         return result;
     }
 
     @JRubyMethod(name = "take_while", compat = )
     public static IRubyObject take_while19(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"take_while");
         }
 
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         try {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext contextIRubyObject[] argsBlock blk) {
                     // note the we do not want to call the block with packed args, since to match MRI behavior,
                     // the block's test is against the raw args (using block.arity() rather than the Arity.OPTIONAL
                     // we pass to callEach)
                     if (!block.call(contextargs).isTrue()) {
                         throw .;
                     }
                     IRubyObject packedArg = packEnumValues(context.runtimeargs);
                     synchronized (result) { result.append(packedArg); }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
         return result;
     }    
 
     @JRubyMethod(name = "drop")
     public static IRubyObject drop(ThreadContext contextIRubyObject selfIRubyObject nfinal Block block) {
         final Ruby runtime = context.runtime;
         final long len = RubyNumeric.num2long(n);
         
         if (len < 0) throw runtime.newArgumentError("attempt to drop negative size");
 
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(runtime.) {
                 long i = len// Atomic ?
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     synchronized (result) {
                         if ( == 0) {
                             // While iterating over an RubyEnumerator, "arg"
                             // gets overwritten by the new value, leading to JRUBY-6892.
                             // So call .dup() whenever appropriate.
                             result.append(arg.isImmediate() ? arg : arg.dup());
                         } else {
                             --;
                         }
                     }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump e) {}
         
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject drop_while(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"drop_while");
         }
 
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(runtimecontext"Enumerable#drop_while".) {
                 boolean memo = false;
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     if (! && !block.yield(contextarg).isTrue())  = true;
                     if (synchronized (result) { result.append(arg); }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
         
         return result;
     }    
 
     @JRubyMethod(name = "first")
     public static IRubyObject first(ThreadContext contextIRubyObject self) {
         final IRubyObject[] holder = new IRubyObject[]{ context.runtime.getNil() };
 
         try {
             each(contextselfnew JavaInternalBlockBody(context.runtimecontextnull.) {
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     holder[0] = arg;
                     throw .;
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
 
         return holder[0];
     }
 
     @JRubyMethod(name = "first")
     public static IRubyObject first(ThreadContext contextIRubyObject selffinal IRubyObject num) {
         int firstCount = RubyNumeric.fix2int(num);
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         if (firstCount < 0) throw runtime.newArgumentError("negative index");
         if (firstCount == 0) return result;
 
         try {
             each(contextselfnew JavaInternalBlockBody(runtimecontextnull.) {
                 private int iter = RubyNumeric.fix2int(num);                
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     result.append(arg);
                     if (-- == 1) throw .;
                     return runtime.getNil();                
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
 
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, compat = .)
     public static IRubyObject to_a(ThreadContext contextIRubyObject self) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, rest = true, compat = .)
     public static IRubyObject to_a(ThreadContext contextIRubyObject selfIRubyObject[] args) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         Helpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(),
                 .new AppendBlockCallback(runtimeresult), context));
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, compat = .)
     public static IRubyObject to_a19(ThreadContext contextIRubyObject self) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         result.infectBy(self);
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, rest = true, compat = .)
     public static IRubyObject to_a19(ThreadContext contextIRubyObject selfIRubyObject[] args) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         Helpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(),
                 .new AppendBlockCallback(runtimeresult), context));
         result.infectBy(self);
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject sort(ThreadContext contextIRubyObject selffinal Block block) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
 
         callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         result.sort_bang(contextblock);
         
         return result;
     }
 
     public static IRubyObject sort_byCommon(final ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final ThreadContext localContext = context// MUST NOT be used across threads
         IRubyObject[][] valuesAndCriteria;
 
         if (self instanceof RubyArray) {
             RubyArray selfArray = (RubyArrayself;
             final IRubyObject[][] valuesAndCriteriaArray = new IRubyObject[selfArray.size()][2];
 
             each(contextselfnew JavaInternalBlockBody(runtime.) {
                 AtomicInteger i = new AtomicInteger(0);
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     IRubyObject[] myVandC = valuesAndCriteriaArray[.getAndIncrement()];
                     myVandC[0] = arg;
                     myVandC[1] = block.yield(contextarg);
                     return runtime.getNil();
                 }
             });
 
             valuesAndCriteria = valuesAndCriteriaArray;
         } else {
             final List<IRubyObject[]> valuesAndCriteriaList = new ArrayList<IRubyObject[]>();
 
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     IRubyObject[] myVandC = new IRubyObject[2];
                     myVandC[0] = larg;
                     myVandC[1] = block.yield(ctxlarg);
                     valuesAndCriteriaList.add(myVandC);
                     return runtime.getNil();
                 }
             });
 
             valuesAndCriteria = valuesAndCriteriaList.toArray(new IRubyObject[valuesAndCriteriaList.size()][]);
         }
 
         Arrays.sort(valuesAndCriterianew Comparator<IRubyObject[]>() {
             public int compare(IRubyObject[] o1IRubyObject[] o2) {
                 return RubyComparable.cmpint(contextinvokedynamic(localContexto1[1], o2[1]), o1[1], o2[1]);
             }
         });
 
 
         IRubyObject dstArray[] = new IRubyObject[valuesAndCriteria.length];
         for (int i = 0; i < dstArray.lengthi++) {
             dstArray[i] = valuesAndCriteria[i][0];
         }
 
         return runtime.newArrayNoCopy(dstArray);
     }
 
     @JRubyMethod
     public static IRubyObject sort_by(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? sort_byCommon(contextselfblock) : enumeratorize(context.runtimeself"sort_by");
     }
 
     @JRubyMethod
     public static IRubyObject grep(ThreadContext contextIRubyObject selffinal IRubyObject patternfinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         if (block.isGiven()) {
             callEach(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     if (pattern.callMethod(ctx"==="larg).isTrue()) {
                         IRubyObject value = block.yield(ctxlarg);
                         synchronized (result) {
                             result.append(value);
                         }
                     }
                     return runtime.getNil();
                 }
             });
         } else {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     if (pattern.callMethod(ctx"==="larg).isTrue()) {
                         synchronized (result) {
                             result.append(larg);
                         }
                     }
                     return runtime.getNil();
                 }
             });
         }
         
         return result;
     }
 
     public static IRubyObject detectCommon(ThreadContext contextIRubyObject selffinal Block block) {
         return detectCommon(contextselfnullblock);
     }
 
     public static IRubyObject detectCommon(ThreadContext contextIRubyObject selfIRubyObject ifnonefinal Block block) {
         final Ruby runtime = context.runtime;
         final IRubyObject result[] = new IRubyObject[] { null };
         final ThreadContext localContext = context;
 
         try {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     checkContext(localContextctx"detect/find");
                     if (block.yield(ctxlarg).isTrue()) {
                         result[0] = larg;
                         throw .;
                     }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {
             return result[0];
         }
 
         return ifnone != null ? ifnone.callMethod(context"call") : runtime.getNil();
     }
 
     @JRubyMethod
     public static IRubyObject detect(ThreadContext contextIRubyObject selffinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextnullblock);
 
         return block.isGiven() ? detectCommon(contextselfblock) : enumeratorize(context.runtimeself"detect");
     }
 
     @JRubyMethod
     public static IRubyObject detect(ThreadContext contextIRubyObject selfIRubyObject ifnonefinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextifnoneblock);
 
         return block.isGiven() ? detectCommon(contextselfifnoneblock) : enumeratorize(context.runtimeself"detect"ifnone);
     }
 
     // FIXME: Custom Array enumeratorize should be made for all of these methods which skip Array without a supplied block.
     @JRubyMethod
     public static IRubyObject find(ThreadContext contextIRubyObject selffinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextnullblock);
 
         return blockGiven ? detectCommon(contextselfblock) : enumeratorize(context.runtimeself"find");
     }
 
     @JRubyMethod
     public static IRubyObject find(ThreadContext contextIRubyObject selfIRubyObject ifnonefinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextifnoneblock);
 
         return blockGiven ? detectCommon(contextselfifnoneblock) :
             enumeratorize(context.runtimeself"find"ifnone);
     }
 
     @JRubyMethod(name = "find_index", compat = )
     public static IRubyObject find_index(ThreadContext contextIRubyObject selffinal Block block) {
         return find_index(contextselfblock.);
     }
 
     @JRubyMethod(name = "find_index", compat = )
     public static IRubyObject find_index19(ThreadContext contextIRubyObject selffinal Block block) {
         return find_index(contextselfblockblock.arity());
     }
 
     public static IRubyObject find_index(ThreadContext contextIRubyObject selffinal Block blockArity callbackArity) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find_index(contextblock);
 
         return blockGiven ? find_indexCommon(contextselfblockcallbackArity) :
             enumeratorize(context.runtimeself"find_index");
     }
 
     @JRubyMethod(name = "find_index", compat = )
     public static IRubyObject find_index19(ThreadContext contextIRubyObject selffinal IRubyObject condfinal Block block) {
         return find_index(contextselfcondblock);
     }
 
     @JRubyMethod(name = "find_index", compat = )
     public static IRubyObject find_index(ThreadContext contextIRubyObject selffinal IRubyObject condfinal Block block) {
         final Ruby runtime = context.runtime;
 
         if (block.isGiven()) runtime.getWarnings().warn(. , "given block not used");
         if (self instanceof RubyArrayreturn ((RubyArrayself).find_index(contextcond);
 
         return find_indexCommon(contextselfcond);
     }
 
     public static IRubyObject find_indexCommon(ThreadContext contextIRubyObject selffinal Block blockArity callbackArity) {
         final Ruby runtime = context.runtime;
         final long result[] = new long[] {0};
 
         try {
             callEach(runtimecontextselfcallbackAritynew BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     if (block.yield(ctxlarg).isTrue()) throw .;
                     result[0]++;
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {
             return RubyFixnum.newFixnum(runtimeresult[0]);
         }
 
         return runtime.getNil();
     }
 
     public static IRubyObject find_indexCommon(ThreadContext contextIRubyObject selffinal IRubyObject cond) {
         final Ruby runtime = context.runtime;
         final long result[] = new long[] {0};
 
         try {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     if (larg.equals(cond)) throw .;
                     result[0]++;
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {
             return RubyFixnum.newFixnum(runtimeresult[0]);
         }
 
         return runtime.getNil();
     }
 
     public static IRubyObject selectCommon(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         callEach(runtimecontextself.new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = packEnumValues(runtimelargs);
                 if (block.yield(ctxlarg).isTrue()) {
                     synchronized (result) {
                         result.append(larg);
                     }
                 }
                 return runtime.getNil();
             }
         });
 
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject select(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? selectCommon(contextselfblock) : enumeratorize(context.runtimeself"select");
     }
 
     @JRubyMethod
     public static IRubyObject find_all(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? selectCommon(contextselfblock) : enumeratorize(context.runtimeself"find_all");
     }
 
     public static IRubyObject rejectCommon(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         callEach(runtimecontextself.new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = packEnumValues(runtimelargs);
                 if (!block.yield(ctxlarg).isTrue()) {
                     synchronized (result) {
                         result.append(larg);
                     }
                 }
                 return runtime.getNil();
             }
         });
 
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject reject(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? rejectCommon(contextselfblock) : enumeratorize(context.runtimeself"reject");
     }
 
     @JRubyMethod(name = {"collect""map"}, compat = .)
     public static IRubyObject collect(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         if (block.isGiven()) {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     IRubyObject value = block.yield(ctxlarg);
                     synchronized (result) {
                         result.append(value);
                     }
                     return runtime.getNil();
                 }
             });
         } else {
             callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         }
         return result;
     }
 
     @JRubyMethod(name = {"collect"}, compat = .)
     public static IRubyObject collect19(ThreadContext contextIRubyObject selffinal Block block) {
         return collectCommon19(contextselfblock"collect");
     }
 
     @JRubyMethod(name = {"map"}, compat = .)
     public static IRubyObject map19(ThreadContext contextIRubyObject selffinal Block block) {
         return collectCommon19(contextselfblock"map");
     }
 
     private static IRubyObject collectCommon19(ThreadContext contextIRubyObject selffinal Block blockString methodName) {
         final Ruby runtime = context.runtime;
         if (block.isGiven()) {
             final RubyArray result = runtime.newArray();
 
             callEach19(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg;
                     boolean newAry = false;
                     if (largs.length == 0) {
                         larg = ctx.nil;
                     } else if (largs.length == 1) {
                         larg = largs[0];
                     } else {
                         newAry = true;
                         larg = RubyArray.newArrayNoCopy(ctx.runtimelargs);
                     }
                     
                     IRubyObject value = newAry ? block.yieldArray(ctxlargnullnull) : block.yield(ctxlarg);
                     synchronized (result) {
                         result.append(value);
                     }
                     return runtime.getNil();
                 }
             });
             return result;
         } else {
             return enumeratorize(runtimeselfmethodName);
         }
     }
 
     public static IRubyObject collectCommon(ThreadContext contextRuby runtimeIRubyObject self,
             RubyArray resultfinal Block blockBlockCallback blockCallback) {
         callEach(runtimecontextself.blockCallback);
         return result;
     }
 
     @JRubyMethod(name = {"flat_map"}, compat = .)
     public static IRubyObject flat_map19(ThreadContext contextIRubyObject selffinal Block block) {
         return flatMapCommon19(contextselfblock"flat_map");
     }
 
     @JRubyMethod(name = {"collect_concat"}, compat = .)
     public static IRubyObject collect_concat19(ThreadContext contextIRubyObject selffinal Block block) {
         return flatMapCommon19(contextselfblock"collect_concat");
     }
 
     private static IRubyObject flatMapCommon19(ThreadContext contextIRubyObject selffinal Block blockString methodName) {
         final Ruby runtime = context.runtime;
         if(block.isGiven()) {
             final RubyArray ary = runtime.newArray();
 
             callEach(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = packEnumValues(runtimelargs);
                     IRubyObject i = block.yield(ctxlarg);
                     IRubyObject tmp = i.checkArrayType();
                     synchronized(ary) {
                         if(tmp.isNil()) {
                             ary.append(i);
                         } else {
                             ary.concat(tmp);
                         }
                     }
                     return runtime.getNil();
                 }
             });
             return ary;
         } else {
             return enumeratorize(runtimeselfmethodName);
         }
     }
 
     public static IRubyObject injectCommon(ThreadContext contextIRubyObject selfIRubyObject initfinal Block block) {
         final Ruby runtime = context.runtime;
         final IRubyObject result[] = new IRubyObject[] { init };
         final ThreadContext localContext = context;
 
         callEach(runtimecontextself.new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = packEnumValues(runtimelargs);
                 checkContext(localContextctx"inject");
                 result[0] = result[0] == null ? 
                         larg : block.yieldArray(ctxruntime.newArray(result[0], larg), nullnull);
 
                 return runtime.getNil();
             }
         });
 
         return result[0] == null ? runtime.getNil() : result[0];
     }
 
     @JRubyMethod(name = {"inject""reduce"})
     public static IRubyObject inject(ThreadContext contextIRubyObject selffinal Block block) {
         return injectCommon(contextselfnullblock);
     }
     
     @JRubyMethod(name = {"inject""reduce"})
     public static IRubyObject inject(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
         return block.isGiven() ? injectCommon(contextselfargblock) : inject(contextselfnullargblock);
     }
 
     @JRubyMethod(name = {"inject""reduce"})