Comments (21)
Otherwise it doesn't stop.
Could you show the example?
I agree it should stop also return
events, but it will stops just another frames.
or another frame can't evaluate because of different bindings?
I think we should improve this.
Maybe this request is, "I want to watch the change of an ivar of THIS object". So it needs to specify two parameters, "Object" and "Ivar name".
I'm planning to introduce watch @ivar of obj
. Does it make sense?
Current watch
command only support "global visible" variables.
Another topic of "watch" command is, should we keep the binding of the frame.
If we keep the binding of "watch" command, we can evaluate "@ivar" of binding, and you don't need to specify "of self". It seems convenient, but it seems too much feature. No conclusion.
from debug.
Could you show the example?
if the change happens at the last line if the program, it doesn't stop there. that's why the tests need an extra line at the end
debug/test/debug/watch_test.rb
Lines 8 to 14 in f44de3a
I'm planning to introduce watch @ivar of obj. Does it make sense?
yeah this feature sounds good 👍 but syntax-wise I'd go for watch obj @ivar
.
Maybe this request is, "I want to watch the change of an ivar of THIS object". So it needs to specify two parameters, "Object" and "Ivar name".
from a user's perspective, if the breakpoint is already inside an object's method, I'd expect watch @var
to just work. for example:
class Foo
def initialize
@var = 0
binding.bp(command: "watch @var")
end
def bar
@var = 10
end
end
f = Foo.new
f.bar
I know this could be hard to implement and may not a be priority right now. but I believe it provides a better user experience.
from debug.
or only allow for ivar (or gvar) like watch @ivar
?
It's simple. Nobody can misuse local_var
.
from debug.
so only:
watch @ivar
watch $gvar
but no watch local
?
what if the breakpoint is inside an instance and I want to watch its method like watch name
(for monitor its return value, not if it's called)? can it distinguish the difference?
from debug.
no watch local
.
The difference is, allow any expression or not.
from debug.
maybe we can preserve watch local
while also improving watch @ivar
? I've given it a try in #58.
from debug.
Maybe we need a scenario to design this feature.
Can you list it?
from debug.
@ko1 do you mean watch @ivar
or watch local
?
I don't think I'd use watch local
very often so I'm ok with dropping it. I just think it'd be great if we can keep it while improving watch @ivar
.
as of watch @ivar
, I'd mainly use it for tracking for variable mutation from the class's source.
for example, tracking down what changes a Student
instance's name:
class Student
attr_accessor :name
def initialize(name)
@name = name
end
end
# somewhere else
student = Student.new("John")
SomeService.perform(student)
without the debugger, it'd take several steps:
- diving into the source code of
SomeService
. - search for
name =
or `name +=...etc. - see if the
student
object is passed into somewhere else. - if there are multiple places that can perform the update, place multiple
puts
orbinding.irb
to verify each of them.
but with debugger & watch @ivar
, I can just do
class Student
attr_accessor :name
def initialize(name)
@name = name
binding.bp(command: "watch @name ;; c")
end
end
then it'll stop at the places where @name
is being updated.
and it's even more convenient than invoking TracePoint
manually, because it can't trace methods generated by attr_*
helpers.
from debug.
btw I think watch local
could be useful in places like this: (watch start_line
& watch end_line
)
debug/lib/debug/thread_client.rb
Lines 248 to 265 in 9d7b88a
from debug.
How about general scenario other than ivars?
btw I think watch local could be useful in places like this: (watch start_line & watch end_line)
The lifetime of local variables are enough small, so I think it is not so important for lvars (if we make a Proc, the lifetime is not limited to the scope though).
from debug.
The lifetime of local variables are enough small, so I think it is not so important for lvars (if we make a Proc, the lifetime is not limited to the scope though).
@ko1 this is generally the case, but I have some real-world examples for the use of watch local
:
The code below comes from a library I use at work and have debugged before:
As you can see, the records
local is assigned multiple times under different conditions. When I debugged it, I had to put a binding.irb
or binding.pry
at every records =
. But with binding.bp(command: "watch records ;; c")
at the top of the method, the debugger would just stop itself. I think that'd be pretty neat.
(although I should note that watch local
is sometimes inaccurate in my application. but we can improve that later).
And here's another example from the same library: https://github.com/cerebris/jsonapi-resources/blob/release-0-9/lib/jsonapi/resource.rb#L1246, which has an even longer method and more local assignments.
Although these cases are not common, they're where this debugger can help the most.
from debug.
Regarding other watch expr
cases, I can only come up with:
$global
- useful for monitoring global state changes, which is sometimes used in test/dev environment.obj.method
- it's helpful when debugging with a class' public interfaces. for example, when debugging anActiveRecord
instance, it's easier to debug withpost.author_name
than watching its instance variables.
from debug.
But with binding.bp(command: "watch records ;; c") at the top of the method, the debugger would just stop itself. I think that'd be pretty neat.
- It makes many watch points (calling the method, making a watch point). And watch points introduce huge overhead. 1 watch makes xN times slower.
- To support
lvar
(or any Ruby syntax on the current frame, likeobj.foo
), we need to keep the binding and it will not be freed.
But for the debug purpose, it is acceptable...?
from debug.
I'm afraid that people ask me to make it fast.
from debug.
For ivar
, I will introduce TracePoint for ivars setting.
For local variables, it should not introduced because of normal performance.
Also obj.foo
notation we can't introduce TP and impossible to support lightweight implementation.
from debug.
To support lvar (or any Ruby syntax on the current frame, like obj.foo), we need to keep the binding and it will not be freed.
I see. Given the performance penalty I think it's reasonable to drop it.
For ivar, I will introduce TracePoint for ivars setting.
I guess the support will come in Ruby 3.1? In that case, will we keep 2 implementations in the debugger? One for 3.1+ and the other for 2.6~3.0
from debug.
Another idea is, shows a warning message "it will make your program super slow" for adding watch points, and doesn't show it ivar on 3.1 with TP optimization.
from debug.
I guess the support will come in Ruby 3.1? In that case, will we keep 2 implementations in the debugger?
For watch points, Yes.
from debug.
@ko1 cool sounds good 👍 I think my PR has improved the ivar case then.
from debug.
@ko1 since we're going to drop expression bp anyway, how about let's just do it in #58?
from debug.
Close this ticket and discuss more features in another issue/PR.
from debug.
Related Issues (20)
- Allow printing out + copying of full variables in VSCode HOT 1
- `rdbg` without no arguments HOT 2
- LocalJumpError: break from proc-closure on typo in debug prompt HOT 2
- Setting breaking points with absolute path fails from nvim-dap and rdbg on Docker container HOT 1
- binding.b doesn't stop code on second controller request and above
- History not available
- Setting the irb_console configuration true has no effect HOT 1
- <enter> does not repeat last command in irb_console mode.
- Proposal: reverse continue
- Feat/Bug: Set the value of `_` (underscore) to the value of the last ruby expression HOT 3
- Slow print (STDOUT) of large objects
- Question: Could not load source 'Fastfile': not found, while debugging a Fastlane lane from VSCODE
- Remove usage of deprecated constant IRB::InputCompletor
- `!!!` to fast forward breakpoints like in pry HOT 5
- Large data output HOT 1
- Add a shorter alias for the whereami command HOT 1
- Could not find valid gem HOT 1
- Cut a new release for the Rails stdin bug HOT 2
- Keystrokes between `debugger` sessions seem to persist HOT 4
- after_fork_parent method waits for all child processes to stop HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from debug.