Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/debug/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,10 @@ def process_event evt
end

wait_command_loop tc

when :sync_prev_evaled
@th_clients.each_value do |tc|
tc << [:store_prev_evaled, ev_args[0]]
end
when :dap_result
dap_event ev_args # server.rb
wait_command_loop tc
Expand Down
10 changes: 10 additions & 0 deletions lib/debug/thread_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def initialize id, q_evt, q_cmd, thr = Thread.current
@obj_map = {} # { object_id => obj } for CDP
@recorder = nil
@mode = :waiting
@prev_evaled_value = nil
set_mode :running
thr.instance_variable_set(:@__thread_client_id, id)

Expand Down Expand Up @@ -358,6 +359,11 @@ def frame_eval src, re_raise: false
b.local_variable_set(name, var) if /\%/ !~ name
end

# this check needs to be performed on the original binding
if !current_frame.binding&.local_variable_defined?(:_)
b.local_variable_set(:_, @prev_evaled_value)
end

result = if b
f, _l = b.source_location
b.eval(src, "(rdbg)/#{f}")
Expand All @@ -366,6 +372,8 @@ def frame_eval src, re_raise: false
instance_eval_for_cmethod(frame_self, src)
end
@success_last_eval = true

event! :sync_prev_evaled, result
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please send SESSION's method. I'll make it.

result

rescue Exception => e
Expand Down Expand Up @@ -824,6 +832,8 @@ def wait_next_action_
end

event! :result, result_type, result
when :store_prev_evaled
@prev_evaled_value = args[0]
when :frame
type, arg = *args
case type
Expand Down
72 changes: 72 additions & 0 deletions test/debug/debugger_local_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,77 @@ def test_raised_doesnt_leak_to_program_binding
end
end
end

class UnderscoreTest < TestCase
def program
<<~RUBY
1| a = 10
2| b = 100
3| binding.b
RUBY
end

def test_underscore_returns_nil_by_default
debug_code(program) do
type "_"
assert_line_text(/nil/)
type "q!"
end
end

def test_underscore_returns_the_previous_value
debug_code(program) do
type "c"
type "a"
assert_line_text(/10/)
type "_ + 40"
assert_line_text(/50/)
type "_ + b"
assert_line_text(/150/)
type "c"
end
end

def test_underscore_ignores_exceptions
debug_code(program) do
type "c"
type "a"
assert_line_text(/10/)
type "a / 0"
assert_line_text(/divided by 0/)
type "_ + 40"
assert_line_text(/50/)
type "c"
end
end

def test_underscore_keeps_value_to_next_bp
debug_code(program) do
type "x = 100"
type "c"
type "_ + 40"
assert_line_text(/140/)
type "c"
end
end

def test_underscore_doesnt_override_program_value
program = <<~RUBY
1| def foo(_)
2| binding.b
3| end
4|
5| foo(100)
RUBY

debug_code(program) do
type "a = 50"
type "c"
type "_"
assert_line_text(/100/)
type "c"
end
end
end
end
end