Skip to content

Instantly share code, notes, and snippets.

@headius
Created January 26, 2012 03:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save headius/1680870 to your computer and use it in GitHub Desktop.
Save headius/1680870 to your computer and use it in GitHub Desktop.
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"
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