Robert said:
That's likely only implementation. Then there is testing,
documentation and before that checking that there are no negative
effects of the change. If there are - and there seems to be evidence
that this is the case in Mark's posting - those negative effects also
count as costs...
Bah, I say.
~/projects/jruby âž” jruby -X-C -e '[1,2,3].each {puts $it}'
1
2
3
Diff follows.
diff --git a/src/org/jruby/RubyGlobal.java b/src/org/jruby/RubyGlobal.java
index f25bd42..c107a7b 100644
--- a/src/org/jruby/RubyGlobal.java
+++ b/src/org/jruby/RubyGlobal.java
@@ -199,6 +199,7 @@ public class RubyGlobal {
runtime.defineVariable(new ErrorInfoGlobalVariable(runtime,
"$!", runtime.getNil()));
runtime.defineVariable(new NonEffectiveGlobalVariable(runtime,
"$=", runtime.getFalse()));
+ runtime.defineVariable(new ImplicitItGlobalVariable(runtime,
"$it"));
if(runtime.getInstanceConfig().getInputFieldSeparator() == null) {
runtime.defineVariable(new GlobalVariable(runtime, "$;",
runtime.getNil()));
@@ -320,6 +321,24 @@ public class RubyGlobal {
}
}
+ private static class ImplicitItGlobalVariable extends GlobalVariable {
+ public ImplicitItGlobalVariable(Ruby runtime, String name) {
+ super(runtime, name, null);
+ }
+
+ @Override
+ public IRubyObject set(IRubyObject value) {
+ return
runtime.getCurrentContext().getCurrentScope().setImplicitArg(value);
+ }
+
+ @Override
+ public IRubyObject get() {
+ IRubyObject obj =
runtime.getCurrentContext().getCurrentScope().getImplicitArg();
+ if (obj == null) obj = runtime.getNil();
+ return obj;
+ }
+ }
+
private static class LastExitStatusVariable extends GlobalVariable {
public LastExitStatusVariable(Ruby runtime, String name) {
super(runtime, name, runtime.getNil());
diff --git a/src/org/jruby/runtime/DynamicScope.java
b/src/org/jruby/runtime/DynamicScope.java
index e2f6e90..9ad9deb 100644
--- a/src/org/jruby/runtime/DynamicScope.java
+++ b/src/org/jruby/runtime/DynamicScope.java
@@ -39,6 +39,8 @@ public abstract class DynamicScope {
// been called.
protected DynamicScope evalScope;
+ protected IRubyObject implicitArg;
+
protected DynamicScope(StaticScope staticScope, DynamicScope parent) {
this.staticScope = staticScope;
this.parent = parent;
@@ -165,6 +167,14 @@ public abstract class DynamicScope {
return staticScope.getAllNamesInScope();
}
+ public IRubyObject getImplicitArg() {
+ return implicitArg;
+ }
+
+ public IRubyObject setImplicitArg(IRubyObject implicitArg) {
+ return this.implicitArg = implicitArg;
+ }
+
/**
* Get backref
*/
diff --git a/src/org/jruby/runtime/InterpretedBlock.java
b/src/org/jruby/runtime/InterpretedBlock.java
index 8015be8..4291066 100644
--- a/src/org/jruby/runtime/InterpretedBlock.java
+++ b/src/org/jruby/runtime/InterpretedBlock.java
@@ -162,6 +162,7 @@ public class InterpretedBlock extends BlockBody {
Frame lastFrame = pre(context, null, binding);
try {
+ context.getCurrentScope().setImplicitArg(value);
if (hasVarNode) {
setupBlockArg(context, varNode, value, self);
}