Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: CPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Common 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/cpl-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 Michael Studman <me@michaelstudman.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 CPL, 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 CPL, the GPL or the LGPL. END LICENSE BLOCK ***
 
 package org.jruby;
 
 import static org.jruby.CompatVersion.*;
 import static org.jruby.runtime.Visibility.*;

Implementation of Ruby's Enumerator module.
 
 @JRubyModule(name="Enumerable::Enumerator", include="Enumerable")
 public class RubyEnumerator extends RubyObject {
    
target for each operation
 
     private IRubyObject object;

    
method to invoke for each operation
 
     private String method;

    
args to each method
 
     private IRubyObject[] methodArgs;
 
     public static void defineEnumerator(Ruby runtime) {
         runtime.getKernel().defineAnnotatedMethods(RubyEnumeratorKernel.class);
 
         RubyModule enm = runtime.getClassFromPath("Enumerable");
 
         final RubyClass enmr;
         if (runtime.is1_9()) {
             enmr = runtime.defineClass("Enumerator"runtime.getObject(), );
         } else {
             enmr = enm.defineClassUnder("Enumerator"runtime.getObject(), );
         }
 
         enmr.includeModule(enm);
         enmr.defineAnnotatedMethods(RubyEnumerator.class);
         runtime.setEnumerator(enmr);
 
         RubyYielder.createYielderClass(runtime);
     }
 
     private static ObjectAllocator ENUMERATOR_ALLOCATOR = new ObjectAllocator() {
         public IRubyObject allocate(Ruby runtimeRubyClass klass) {
             return new RubyEnumerator(runtimeklass);
         }
     };
 
     private RubyEnumerator(Ruby runtimeRubyClass type) {
         super(runtimetype);
          = runtime.getNil();
         initialize(runtime.getNil(), RubyString.newEmptyString(runtime), .);
     }
 
     private RubyEnumerator(Ruby runtimeIRubyObject objectIRubyObject methodIRubyObject[]args) {
         super(runtimeruntime.getEnumerator());
         initialize(objectmethodargs);
     }
 
     public static IRubyObject enumeratorize(Ruby runtimeIRubyObject objectString method) {
         return new RubyEnumerator(runtimeobjectruntime.fastNewSymbol(method), .);
     }
 
     public static IRubyObject enumeratorize(Ruby runtimeIRubyObject objectString methodIRubyObject arg) {
         return new RubyEnumerator(runtimeobjectruntime.fastNewSymbol(method), new IRubyObject[]{arg});
    }
    public static IRubyObject enumeratorize(Ruby runtimeIRubyObject objectString methodIRubyObject[]args) {
        return new RubyEnumerator(runtimeobjectruntime.fastNewSymbol(method), args); // TODO: make sure it's really safe to not to copy it
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize(ThreadContext context) {
        throw context.runtime.newArgumentError(0, 1);
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize19(ThreadContext contextBlock block) {
        if(!block.isGiven()) {
            throw context.runtime.newArgumentError(0, 1);
        }
        // TODO: avoid double lookup
        IRubyObject obj = context.runtime.getModule("JRuby").getClass("Generator").callMethod(context"new"new IRubyObject[0], block);
        return initialize19(contextobjblock);
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize(ThreadContext contextIRubyObject object) {
        return initialize(objectcontext.runtime.fastNewSymbol("each"), );
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize19(ThreadContext contextIRubyObject objectBlock block) {
        return initialize(objectcontext.runtime.fastNewSymbol("each"), );
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize(ThreadContext contextIRubyObject objectIRubyObject method) {
        return initialize(objectmethod);
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize19(ThreadContext contextIRubyObject objectIRubyObject methodBlock block) {
        return initialize(objectmethod);
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize(ThreadContext contextIRubyObject objectIRubyObject methodIRubyObject methodArg) {
        return initialize(objectmethodnew IRubyObject[] { methodArg });
    }
    @JRubyMethod(name = "initialize", visibility = , compat = )
    public IRubyObject initialize19(ThreadContext contextIRubyObject objectIRubyObject methodIRubyObject methodArgBlock block) {
        return initialize(objectmethodnew IRubyObject[] { methodArg });
    }
    @JRubyMethod(name = "initialize", rest = true, visibility = , compat = )
    public IRubyObject initialize(ThreadContext contextIRubyObject[] args) {
        switch (args.length) {
            case 0: return initialize(context);
            case 1: return initialize(contextargs[0]);
            case 2: return initialize(contextargs[0], args[1]);
        }
        IRubyObject[] methArgs = new IRubyObject[args.length - 2];
        System.arraycopy(args, 2, methArgs, 0, methArgs.length);
        return initialize(args[0], args[1], methArgs);
    }
    @JRubyMethod(name = "initialize", rest = true, visibility = , compat = )
    public IRubyObject initialize19(ThreadContext contextIRubyObject[] argsBlock block) {
        switch (args.length) {
            case 0: return initialize19(contextblock);
            case 1: return initialize19(contextargs[0], block);
            case 2: return initialize19(contextargs[0], args[1], block);
        }
        IRubyObject[] methArgs = new IRubyObject[args.length - 2];
        System.arraycopy(args, 2, methArgs, 0, methArgs.length);
        return initialize(args[0], args[1], methArgs);
    }
    private IRubyObject initialize(IRubyObject objectIRubyObject methodIRubyObject[] methodArgs) {
        this. = object;
        this. = method.asJavaString();
        this. = methodArgs;
        setInstanceVariable("@__object__"object);
        setInstanceVariable("@__method__"method);
        setInstanceVariable("@__args__", RubyArray.newArrayNoCopyLight(getRuntime(), methodArgs));
        return this;
    }
    @JRubyMethod(name = "dup")
    @Override
    public IRubyObject dup() {
        // JRUBY-5013: Enumerator needs to copy private fields in order to have a valid structure
        RubyEnumerator copy = (RubyEnumeratorsuper.dup();
        copy.object     = this.;
        copy.method     = this.;
        copy.methodArgs = this.;
        return copy;
    }

    
Send current block and supplied args to method on target. According to MRI Block may not be given and "each" should just ignore it and call on through to underlying method.
    public IRubyObject each(ThreadContext contextBlock block) {
        return .callMethod(contextblock);
    }
    @JRubyMethod(name = "inspect", compat = )
    public IRubyObject inspect19(ThreadContext context) {
        Ruby runtime = context.runtime;
        if (runtime.isInspecting(this)) return inspect(contexttrue);
        try {
            runtime.registerInspecting(this);
            return inspect(contextfalse);
        } finally {
            runtime.unregisterInspecting(this);
        }
    }
    private IRubyObject inspect(ThreadContext contextboolean recurse) {
        Ruby runtime = context.runtime;
        ByteList bytes = new ByteList();
        bytes.append((byte)'#').append((byte)'<');
        bytes.append(getMetaClass().getName().getBytes());
        bytes.append((byte)':').append((byte)' ');
        if (recurse) {
            bytes.append("...>".getBytes());
            return RubyString.newStringNoCopy(runtimebytes).taint(context);
        } else {
            boolean tainted = isTaint();
            bytes.append(RubyObject.inspect(context).getByteList());
            bytes.append((byte)':');
            bytes.append(.getBytes());
            if (. > 0) {
                bytes.append((byte)'(');
                for (int i= 0; i < .i++) {
                    bytes.append(RubyObject.inspect(context[i]).getByteList());
                    if (i < . - 1) {
                        bytes.append((byte)',').append((byte)' ');
                    } else {
                        bytes.append((byte)')');
                    }
                    if ([i].isTaint()) tainted = true;
                }
            }
            bytes.append((byte)'>');
            RubyString result = RubyString.newStringNoCopy(runtimebytes);
            if (taintedresult.setTaint(true);
            return result;
        }
    }
    protected static IRubyObject newEnumerator(ThreadContext contextIRubyObject arg) {
        return context.runtime.getEnumerator().callMethod(context"new"arg);
    }
    protected static IRubyObject newEnumerator(ThreadContext contextIRubyObject arg1IRubyObject arg2) {
        return RuntimeHelpers.invoke(contextcontext.runtime.getEnumerator(), "new"arg1arg2);
    }
    protected static IRubyObject newEnumerator(ThreadContext contextIRubyObject arg1IRubyObject arg2IRubyObject arg3) {
        return RuntimeHelpers.invoke(contextcontext.runtime.getEnumerator(), "new"arg1arg2arg3);
    }
    public static final class RubyEnumeratorKernel {
        @JRubyMethod(name = {"to_enum""enum_for"})
        public static IRubyObject obj_to_enum(ThreadContext contextIRubyObject self) {
            return newEnumerator(contextself);
        }
        @JRubyMethod(name = {"to_enum""enum_for"})
        public static IRubyObject obj_to_enum(ThreadContext contextIRubyObject selfIRubyObject arg) {
            return newEnumerator(contextselfarg);
        }
        @JRubyMethod(name = {"to_enum""enum_for"})
        public static IRubyObject obj_to_enum(ThreadContext contextIRubyObject selfIRubyObject arg0IRubyObject arg1) {
            return newEnumerator(contextselfarg0arg1);
        }
        @JRubyMethod(name = {"to_enum""enum_for"}, optional = 1, rest = true)
        public static IRubyObject obj_to_enum(ThreadContext contextIRubyObject selfIRubyObject[] args) {
            IRubyObject[] newArgs = new IRubyObject[args.length + 1];
            newArgs[0] = self;
            System.arraycopy(args, 0, newArgs, 1, args.length);
            return context.runtime.getEnumerator().callMethod(context"new"newArgs);
        }
    }
    public static final class RubyEnumeratorEnumerable {
        public static IRubyObject each_slice(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
            final int size = RubyNumeric.num2int(arg);
            final Ruby runtime = context.runtime;
            if (size <= 0) throw runtime.newArgumentError("invalid slice size");
            final RubyArray result[] = new RubyArray[]{runtime.newArray(size)};
            RubyEnumerable.callEach(runtimecontextself.new BlockCallback() {
                public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                    result[0].append(largs[0]);
                    if (result[0].size() == size) {
                        block.yield(ctxresult[0]);
                        result[0] = runtime.newArray(size);
                    }
                    return runtime.getNil();
                }
            });
            if (result[0].size() > 0) block.yield(contextresult[0]);
            return context.runtime.getNil();
        }
        @JRubyMethod(name = "each_slice")
        public static IRubyObject each_slice19(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
            return block.isGiven() ? each_slice(contextselfargblock) : enumeratorize(context.runtimeself"each_slice"arg);
        }
        @JRubyMethod(name = "enum_slice")
        public static IRubyObject enum_slice19(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
            return block.isGiven() ? each_slice(contextselfargblock) : enumeratorize(context.runtimeself"enum_slice"arg);
        }
        public static IRubyObject each_cons(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
            final int size = (int)RubyNumeric.num2long(arg);
            final Ruby runtime = context.runtime;
            if (size <= 0) throw runtime.newArgumentError("invalid size");
            final RubyArray result = runtime.newArray(size);
            RubyEnumerable.callEach(runtimecontextself.new BlockCallback() {
                public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                    if (result.size() == sizeresult.shift(ctx);
                    result.append(largs[0]);
                    if (result.size() == sizeblock.yield(ctxresult.aryDup());
                    return runtime.getNil();
                }
            });
            return runtime.getNil();        
        }
        @JRubyMethod(name = "each_cons")
        public static IRubyObject each_cons19(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
            return block.isGiven() ? each_cons(contextselfargblock) : enumeratorize(context.runtimeself"each_cons"arg);
        }
        @JRubyMethod(name = "enum_cons")
        public static IRubyObject enum_cons19(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
            return block.isGiven() ? each_cons(contextselfargblock) : enumeratorize(context.runtimeself"enum_cons"arg);
        }
        @JRubyMethod(name = "each_with_object", compat = )
        public static IRubyObject each_with_object(ThreadContext contextIRubyObject selffinal IRubyObject argfinal Block block) {
            return with_object_common(contextselfargblock"each_with_object");
        }
        @JRubyMethod(name = "with_object", compat = )
        public static IRubyObject with_object(ThreadContext contextIRubyObject selffinal IRubyObject argfinal Block block) {
            return with_object_common(contextselfargblock"with_object");
        }
        private static IRubyObject with_object_common(ThreadContext contextIRubyObject self,
                final IRubyObject argfinal Block blockfinal String rubyMethodName) {
            final Ruby runtime = context.runtime;
            if (!block.isGiven()) return enumeratorize(runtimeself , rubyMethodNamearg);
            RubyEnumerable.callEach(runtimecontextself.new BlockCallback() {
                public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                    block.call(ctxnew IRubyObject[]{runtime.newArray(largs[0], arg)});
                    return runtime.getNil();
                }
            });
            return arg;
        }
    }
    private static class EachWithIndex implements BlockCallback {
        private int index = 0;
        private final Block block;
        private final Ruby runtime;
        public EachWithIndex(ThreadContext ctxBlock blockint index) {
            this. = block;
            this. = ctx.runtime;
            this. = index;
        }
        public IRubyObject call(ThreadContext contextIRubyObject[] iargsBlock block) {
            return this..call(contextnew IRubyObject[] { .newArray(RubyEnumerable.checkArgs(iargs), .newFixnum(++)) });
        }
    }
    private static IRubyObject with_index_common(ThreadContext contextIRubyObject self
            final Block blockfinal String rubyMethodNameIRubyObject arg) {
        final Ruby runtime = context.runtime;
        int index = arg.isNil() ? 0 : RubyNumeric.num2int(arg);
        if (!block.isGiven()) {
            return arg.isNil() ? enumeratorize(runtimeself , rubyMethodName) :
                enumeratorize(runtimeself , rubyMethodNameruntime.newFixnum(index));
        }
        return RubyEnumerable.callEach(runtimecontextselfnew EachWithIndex(contextblockindex));
    }
    public static IRubyObject each_with_index(ThreadContext contextIRubyObject selffinal Block block) {
        return with_index_common(contextselfblock"each_with_index"context.runtime.getNil());
    }
    @JRubyMethod(compat = )
    public static IRubyObject with_index(ThreadContext contextIRubyObject selffinal Block block) {
        return with_index_common(contextselfblock"with_index"context.runtime.getNil());
    }
    @JRubyMethod(name = "with_index", compat = )
    public static IRubyObject with_index19(ThreadContext contextIRubyObject selffinal Block block) {
        return with_index_common(contextselfblock"with_index"context.runtime.getNil());
    }
    @JRubyMethod(name = "with_index", compat = )
    public static IRubyObject with_index19(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
        return with_index_common(contextselfblock"with_index"arg);
    }
New to GrepCode? Check out our FAQ X