-
-
Save banister/1680878 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
system ~/projects/jruby $ jirb | |
>> require 'java' | |
=> true | |
>> binding = Thread.current.to_java.getContext.nth_binding(4) | |
=> #<Java::OrgJrubyRuntime::Binding:0x304648> | |
>> binding = org.jruby.RubyBinding.new(JRuby.runtime, JRuby.runtime.binding, binding) | |
=> #<Binding:0x8b3bb3> | |
>> binding = JRuby.dereference(binding) | |
=> #<Binding:0x8b3bb3> | |
>> eval "__FILE__", binding | |
=> "/Users/headius/projects/jruby/lib/ruby/1.8/irb.rb" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/org/jruby/runtime/ThreadContext.java b/src/org/jruby/runtime/ThreadContext.java | |
index 383efd9..6c1cdcb 100644 | |
--- a/src/org/jruby/runtime/ThreadContext.java | |
+++ b/src/org/jruby/runtime/ThreadContext.java | |
@@ -229,6 +229,10 @@ public final class ThreadContext { | |
public DynamicScope getPreviousScope() { | |
return scopeStack[scopeIndex - 1]; | |
} | |
+ | |
+ public DynamicScope getNthPreviousScope(int n) { | |
+ return scopeStack[scopeIndex - n]; | |
+ } | |
private void expandFramesIfNecessary() { | |
int newSize = frameStack.length * 2; | |
@@ -434,6 +438,11 @@ public final class ThreadContext { | |
int index = frameIndex; | |
return index < 1 ? null : frameStack[index - 1]; | |
} | |
+ | |
+ public Frame getNthPreviousFrame(int n) { | |
+ int index = frameIndex; | |
+ return index < n ? null : frameStack[index - n]; | |
+ } | |
public int getFrameCount() { | |
return frameIndex + 1; | |
@@ -635,6 +644,12 @@ public final class ThreadContext { | |
RubyModule parentModule = parentStack[parentIndex - 1]; | |
return parentModule.getNonIncludedClass(); | |
} | |
+ | |
+ public RubyModule getNthPreviousRubyClass(int n) { | |
+ assert parentIndex - n >= 0 : "Trying to get RubyClass from too-shallow stack"; | |
+ RubyModule parentModule = parentStack[parentIndex - n]; | |
+ return parentModule.getNonIncludedClass(); | |
+ } | |
public boolean getConstantDefined(String internedName) { | |
IRubyObject value = getConstant(internedName); | |
@@ -1241,6 +1256,22 @@ public final class ThreadContext { | |
} | |
/** | |
+ * Return a binding representing the nth previous call's state. | |
+ * | |
+ * Only interesting for experimentation; interpreted mode is recommended. | |
+ * | |
+ * @return the nth caller's binding. | |
+ */ | |
+ public Binding nthBinding(int n) { | |
+ if (n == 1) { | |
+ return previousBinding(); | |
+ } else { | |
+ Frame frame = getNthPreviousFrame(n); | |
+ return new Binding(frame, getNthPreviousRubyClass(n), getNthPreviousScope(n - 1), backtrace[backtraceIndex - (n - 1)].clone()); | |
+ } | |
+ } | |
+ | |
+ /** | |
* Return a binding representing the previous call's state | |
* @return the current binding | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment