private IRubyObject stepCommon(ThreadContext context, IRubyObject step, Block block) { final Ruby runtime = context.getRuntime(); long unit = RubyNumeric.num2long(step); if (unit < 0) throw runtime.newArgumentError("step can't be negative"); if (begin instanceof RubyFixnum && end instanceof RubyFixnum) { if (unit == 0) throw runtime.newArgumentError("step can't be 0"); fixnumStep(context, runtime, unit, block); } else { IRubyObject tmp = begin.checkStringType(); if (!tmp.isNil()) { if (unit == 0) throw runtime.newArgumentError("step can't be 0"); // rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i, (VALUE)iter); StepBlockCallBack callback = new StepBlockCallBack(block, RubyFixnum.one(runtime), step); Block blockCallback = CallBlock.newCallClosure( this, runtime.getRange(), Arity.singleArgument(), callback, context); ((RubyString) tmp).uptoCommon(context, end, isExclusive, blockCallback); } else if (begin instanceof RubyNumeric) { if (equalInternal(context, step, RubyFixnum.zero(runtime))) throw runtime.newArgumentError("step can't be 0"); numericStep(context, runtime, step, block); } else { if (unit == 0) throw runtime.newArgumentError("step can't be 0"); if (!begin.respondsTo("succ")) throw runtime.newTypeError("can't iterate from " + begin.getMetaClass().getName()); // range_each_func(range, step_i, b, e, args); rangeEach(context, new StepBlockCallBack(block, RubyFixnum.one(runtime), step)); } } return this; }
private IRubyObject stepCommon19(ThreadContext context, IRubyObject step, Block block) { Ruby runtime = context.getRuntime(); if (begin instanceof RubyFixnum && end instanceof RubyFixnum && step instanceof RubyFixnum) { fixnumStep(context, runtime, ((RubyFixnum) step).getLongValue(), block); } else if (begin instanceof RubyFloat || end instanceof RubyFloat || step instanceof RubyFloat) { RubyNumeric.floatStep19(context, runtime, begin, end, step, isExclusive, block); } else if (begin instanceof RubyNumeric || !checkIntegerType(runtime, begin, "to_int").isNil() || !checkIntegerType(runtime, end, "to_int").isNil()) { numericStep19(context, runtime, step, block); } else { IRubyObject tmp = begin.checkStringType(); if (!tmp.isNil()) { StepBlockCallBack callback = new StepBlockCallBack(block, RubyFixnum.one(runtime), step); Block blockCallback = CallBlock.newCallClosure( this, runtime.getRange(), Arity.singleArgument(), callback, context); ((RubyString) tmp).uptoCommon19(context, end, isExclusive, blockCallback); } else { if (!begin.respondsTo("succ")) throw runtime.newTypeError("can't iterate from " + begin.getMetaClass().getName()); // range_each_func(range, step_i, b, e, args); rangeEach(context, new StepBlockCallBack(block, RubyFixnum.one(runtime), step)); } } return this; }
@JRubyMethod(name = "each", frame = true, compat = CompatVersion.RUBY1_8) public IRubyObject each(ThreadContext context, final Block block) { final Ruby runtime = context.getRuntime(); if (begin instanceof RubyFixnum && end instanceof RubyFixnum) { fixnumEach(context, runtime, block); } else if (begin instanceof RubyString) { ((RubyString) begin).uptoCommon(context, end, isExclusive, block); } else { if (!begin.respondsTo("succ")) throw getRuntime().newTypeError("can't iterate from " + begin.getMetaClass().getName()); rangeEach( context, new RangeCallBack() { @Override void call(ThreadContext context, IRubyObject arg) { block.yield(context, arg); } }); } return this; }