Skip to content

Commit 7774be5

Browse files
committed
Use target obj as self for instance_eval. Fixes #2301.
1 parent 870f979 commit 7774be5

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

core/src/main/java/org/jruby/RubyBasicObject.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,7 @@ public IRubyObject instance_exec19(ThreadContext context, IRubyObject[] args, Bl
15741574
* with this implementation.
15751575
*/
15761576
protected IRubyObject yieldUnder(final ThreadContext context, RubyModule under, IRubyObject[] args, Block block) {
1577-
context.preExecuteUnder(under, block);
1577+
context.preExecuteUnder(this, under, block);
15781578

15791579
IRubyObject savedBindingSelf = block.getBinding().getSelf();
15801580
IRubyObject savedFrameSelf = block.getBinding().getFrame().getSelf();
@@ -1616,7 +1616,7 @@ private Block setupBlock(Block block) {
16161616
* with this implementation.
16171617
*/
16181618
protected IRubyObject yieldUnder(final ThreadContext context, RubyModule under, Block block) {
1619-
context.preExecuteUnder(under, block);
1619+
context.preExecuteUnder(this, under, block);
16201620

16211621
IRubyObject savedBindingSelf = block.getBinding().getSelf();
16221622
IRubyObject savedFrameSelf = block.getBinding().getFrame().getSelf();
@@ -1759,7 +1759,7 @@ protected RubyModule getInstanceEvalClass() {
17591759
public IRubyObject evalUnder(final ThreadContext context, RubyModule under, RubyString src, String file, int line) {
17601760
Visibility savedVisibility = context.getCurrentVisibility();
17611761
context.setCurrentVisibility(PUBLIC);
1762-
context.preExecuteUnder(under, Block.NULL_BLOCK);
1762+
context.preExecuteUnder(this, under, Block.NULL_BLOCK);
17631763
try {
17641764
return ASTInterpreter.evalSimple(context, this, src,
17651765
file, line);

core/src/main/java/org/jruby/runtime/ThreadContext.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,20 +1176,19 @@ public void postNodeEval() {
11761176
popFrame();
11771177
popRubyClass();
11781178
}
1179-
1180-
// XXX: Again, screwy evaling under previous frame's scope
1181-
public void preExecuteUnder(RubyModule executeUnderClass, Block block) {
1179+
1180+
public void preExecuteUnder(IRubyObject self, RubyModule executeUnderClass, Block block) {
11821181
Frame frame = getCurrentFrame();
1183-
1182+
11841183
pushRubyClass(executeUnderClass);
11851184
DynamicScope scope = getCurrentScope();
11861185
StaticScope sScope = runtime.getStaticScopeFactory().newBlockScope(scope.getStaticScope());
11871186
sScope.setModule(executeUnderClass);
11881187
pushScope(DynamicScope.newDynamicScope(sScope, scope));
1189-
pushCallFrame(frame.getKlazz(), frame.getName(), frame.getSelf(), block);
1188+
pushCallFrame(frame.getKlazz(), frame.getName(), self, block);
11901189
getCurrentFrame().setVisibility(getPreviousFrame().getVisibility());
11911190
}
1192-
1191+
11931192
public void postExecuteUnder() {
11941193
popFrame();
11951194
popScope();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
describe "Object#instance_eval" do
2+
it "uses the target object as self in the executed code" do
3+
o = Object.new
4+
o.instance_variable_set :@foo, 1
5+
newself, binding = o.instance_eval "[self, binding]"
6+
expect(newself).to eq(o)
7+
expect(eval('self', binding)).to eq(self)
8+
9+
newself, binding = o.instance_eval {[self, binding]}
10+
expect(newself).to eq(o)
11+
expect(eval('self', binding)).to eq(self)
12+
end
13+
end

0 commit comments

Comments
 (0)