Skip to content

Commit d36c3f4

Browse files
HeyNonsterbquorningzendesk-edytarozrazumaubatizhevsky
committed
Set evaluation result to _ local variable
This PR makes a change to the thread client to set the `_` local variable to the result of the last evaluation similar to the behavior in irb[^1]. The reason `_` doesn't work even when using the `irb` console is because we leave the `irb` evaluation early if the input should be handled by the debugger[^2]. Otherwise, we would end up in IRB::Context#evaluate` and we would call `set_last_value`[^3]. There's a bit of a quirk here when using the `irb` console. I was hoping in `thread_client` to evaluate the result then set the `_` local variable and the `@last_value` ivar all in the same method, similar to how `irb` does it[^1]. However, because we're using the `irb` console we use a new `irb` `Workspace` which nils out `_` when initialized[^4]. To get around that, we set the local variable just before evaluating. [^1]:(https://github.com/ruby/irb/blob/d43c3d764ae439706aa1b26a3ec299cc45eaed5b/lib/irb/context.rb#L460-L465) [^2]:(https://github.com/ruby/irb/blob/d43c3d764ae439706aa1b26a3ec299cc45eaed5b/lib/irb.rb#L195-L198) [^3]:(https://github.com/ruby/irb/blob/d43c3d764ae439706aa1b26a3ec299cc45eaed5b/lib/irb/context.rb#L550-L558) [^4]:(https://github.com/ruby/irb/blob/d43c3d764ae439706aa1b26a3ec299cc45eaed5b/lib/irb/workspace.rb#L81) This PR was created by Zendesk's Ruby infrastructure team: Co-authored-by: Benjamin Quorning <bquorning@zendesk.com> Co-authored-by: Edyta Rozczypała <edyta.rozczypala@zendesk.com> Co-authored-by: Jury Razumau <jury.razumau@zendesk.com> Co-authored-by: Leonid Batizhevskii <leonid.batizhevskii@zendesk.com> Co-authored-by: Luis Manotas <lgerman@gmail.com> Co-authored-by: Thomas Countz <thomascountz@gmail.com>
1 parent 14c8a54 commit d36c3f4

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

lib/debug/thread_client.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,9 @@ def frame_eval src, re_raise: false, binding_location: false
443443
b.local_variable_set(name, var) if /\%/ !~ name
444444
end
445445

446+
b.local_variable_set(:_, @last_result)
446447
result = frame_eval_core(src, b, binding_location: binding_location)
448+
@last_result = result
447449

448450
@success_last_eval = true
449451
result

test/console/debugger_local_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ def test_locals_added_in_locals_are_accessible_between_evaluations
1919
type "c"
2020
end
2121
end
22+
23+
def test_evaluated_result_is_set_as_underscore_local
24+
debug_code(program) do
25+
type "_"
26+
assert_line_text(/nil/)
27+
type "3 * 3"
28+
type "foo = _"
29+
type "9 == foo"
30+
assert_line_text(/true/)
31+
type "c"
32+
end
33+
end
2234
end
2335

2436
class RaisedTest < ConsoleTestCase

test/console/irb_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ def test_irb_console_config_activates_irb
8484
ENV["RUBY_DEBUG_IRB_CONSOLE"] = nil
8585
end
8686

87+
def test_irb_console_evaluated_result_is_set_as_underscore_local
88+
debug_code(program, remote: false) do
89+
type 'irb'
90+
type "_"
91+
assert_line_text(/nil/)
92+
type "3 * 3"
93+
assert_raw_line_text 'irb:rdbg(main):003> 3 * 3'
94+
type "foo = _"
95+
type "9 == foo"
96+
assert_line_text(/true/)
97+
type "c"
98+
end
99+
end
100+
87101
private
88102

89103
# assert_line_text ignores the prompt line, so we can't use it to assert the prompt transition

0 commit comments

Comments
 (0)