[ruby-core:120428] [Ruby master Feature#20987] Add dbg - minimal debugging helper

Issue #20987 has been reported by pawurb (Pawel Urbanek). ---------------------------------------- Feature #20987: Add dbg - minimal debugging helper https://bugs.ruby-lang.org/issues/20987 * Author: pawurb (Pawel Urbanek) * Status: Open ---------------------------------------- Hi. It's my first time contributing here, so I'm sorry in advance if I've mixed something up. I’m author of https://github.com/pawurb/dbg-rb gem. `dbg` method is inspired by Rust where it's built-in into std-lib (https://doc.rust-lang.org/std/macro.dbg.html). AFAIK in Ruby there's no simple mechanism to puts debug values together with caller info without using external dependencies. What’s more frustrating is that while `p nil` outputs `nil` to the std, `puts nil` prints a blank line, sometimes making debugging sessions confusing. I would like to propose adding a minimal `dbg` helper method to stdlib: ``` dbg("Hello world", [1, 2, 3]) # => [dir/file.rb:12] "Hello world" # => [dir/file.rb:12] [1, 2, 3] ``` `dbg` will produce verbose output together with informative file name and LOC info. I think that such built-in feature would be useful for many Ruby devs. My gem uses external dependencies, but I've came up with this barebones implementation: ``` def dbg(*msgs) loc = caller_locations.first.to_s matching_loc = loc.match(/.+(rb)\:\d+\:(in)\s/) src = if matching_loc.nil? loc else matching_loc[0][0..-5] end file, line = src.split(":") file = file.split("/").last(2).join("/") src = "[#{file}:#{line}]" msgs.each do |msg| puts "#{src} #{msg.inspect}" end nil end ``` ---Files-------------------------------- Screenshot 2024-12-27 at 00.00.23.png (81.5 KB) -- https://bugs.ruby-lang.org/

Issue #20987 has been updated by pawurb (Pawel Urbanek). Hi. It's my first time contributing here, so I'm sorry in advance if I've mixed something up. I’m author of [dbg-rb gem](https://github.com/pawurb/dbg-rb). `dbg` method is inspired by Rust where it's [built-in into std-lib](https://doc.rust-lang.org/std/macro.dbg.html). AFAIK in Ruby there's no simple mechanism to puts debug values together with caller info without using external dependencies. What’s more frustrating is that while `p nil` outputs `nil` to the std, `puts nil` prints a blank line, sometimes making debugging sessions confusing. I would like to propose adding a minimal dbg helper method to stdlib: ```ruby dbg("Hello world", [1, 2, 3]) # => [dir/file.rb:12] "Hello world" # => [dir/file.rb:12] [1, 2, 3] ``` `dbg` will produce verbose output together with informative file name and LOC info. I think that such built-in feature would be useful for many Ruby devs. My gem uses external dependencies, but I've came up with this barebones implementation: ```ruby def dbg(*msgs) loc = caller_locations.first file = if (path = loc.absolute_path) path.split("/").last(2).join("/") else loc.label end line = loc.lineno src = "[#{file}:#{line}]" msgs.each do |msg| puts "#{src} #{msg.inspect}" end nil end ``` ---------------------------------------- Feature #20987: Add dbg - minimal debugging helper https://bugs.ruby-lang.org/issues/20987#change-111209 * Author: pawurb (Pawel Urbanek) * Status: Open ---------------------------------------- Hi. It's my first time contributing here, so I'm sorry in advance if I've mixed something up. I’m author of https://github.com/pawurb/dbg-rb gem. `dbg` method is inspired by Rust where it's built-in into std-lib (https://doc.rust-lang.org/std/macro.dbg.html). AFAIK in Ruby there's no simple mechanism to puts debug values together with caller info without using external dependencies. What’s more frustrating is that while `p nil` outputs `nil` to the std, `puts nil` prints a blank line, sometimes making debugging sessions confusing. I would like to propose adding a minimal `dbg` helper method to stdlib: ``` dbg("Hello world", [1, 2, 3]) # => [dir/file.rb:12] "Hello world" # => [dir/file.rb:12] [1, 2, 3] ``` `dbg` will produce verbose output together with informative file name and LOC info. I think that such built-in feature would be useful for many Ruby devs. My gem uses external dependencies, but I've came up with this barebones implementation: ``` def dbg(*msgs) loc = caller_locations.first.to_s matching_loc = loc.match(/.+(rb)\:\d+\:(in)\s/) src = if matching_loc.nil? loc else matching_loc[0][0..-5] end file, line = src.split(":") file = file.split("/").last(2).join("/") src = "[#{file}:#{line}]" msgs.each do |msg| puts "#{src} #{msg.inspect}" end nil end ``` ---Files-------------------------------- Screenshot 2024-12-27 at 00.00.23.png (81.5 KB) -- https://bugs.ruby-lang.org/

Issue #20987 has been updated by mame (Yusuke Endoh). Basically, I like this proposal. I use `Kernel#p` and `pp` a lot when debugging. I often include an identifier such as `p [:foo, obj]`, `p [:bar, obj]` to distinguish which `p` the output is from. If the debug output method itself prints the caller filename, this identifier might be unnecessary. (But TBH, I am not sure. The filename and line number could be insufficient for easy recognition.) Also, I delete all calls to `p` after debugging is done, but it is sometimes difficult to find all `p` calls. If `p` would output the filename, the deletion process would be definitely easy. I think it would be better to extend `p` instead of introducing `dbg`. Three letters are too long for every debug method call. As for a concern, it may be troublesome for `p` to always print the filename. Just an idea, how about opt-in by an environment variable? ``` $ ruby foo.rb "Hello world". $ P=1 ruby foo.rb [foo.rb:1] "Hello world" ``` ---------------------------------------- Feature #20987: Add dbg - minimal debugging helper https://bugs.ruby-lang.org/issues/20987#change-111210 * Author: pawurb (Pawel Urbanek) * Status: Open ---------------------------------------- Hi. It's my first time contributing here, so I'm sorry in advance if I've mixed something up. I’m author of https://github.com/pawurb/dbg-rb gem. `dbg` method is inspired by Rust where it's built-in into std-lib (https://doc.rust-lang.org/std/macro.dbg.html). AFAIK in Ruby there's no simple mechanism to puts debug values together with caller info without using external dependencies. What’s more frustrating is that while `p nil` outputs `nil` to the std, `puts nil` prints a blank line, sometimes making debugging sessions confusing. I would like to propose adding a minimal `dbg` helper method to stdlib: ``` dbg("Hello world", [1, 2, 3]) # => [dir/file.rb:12] "Hello world" # => [dir/file.rb:12] [1, 2, 3] ``` `dbg` will produce verbose output together with informative file name and LOC info. I think that such built-in feature would be useful for many Ruby devs. My gem uses external dependencies, but I've came up with this barebones implementation: ``` def dbg(*msgs) loc = caller_locations.first.to_s matching_loc = loc.match(/.+(rb)\:\d+\:(in)\s/) src = if matching_loc.nil? loc else matching_loc[0][0..-5] end file, line = src.split(":") file = file.split("/").last(2).join("/") src = "[#{file}:#{line}]" msgs.each do |msg| puts "#{src} #{msg.inspect}" end nil end ``` ---Files-------------------------------- Screenshot 2024-12-27 at 00.00.23.png (81.5 KB) -- https://bugs.ruby-lang.org/

Issue #20987 has been updated by pawurb (Pawel Urbanek). Thanks for feedback! One thing I'm worried about with `P=1` approach, are Ruby programs that rely on the current `p` output, making it impossible to opt-in this new feature. Maybe we could go for `d` instead of `dbg`? As for identifiers, [dbg-rb gem](https://github.com/pawurb/dbg-rb) currently supports passing local variables via symbols like this: ```ruby a = 1 b = 2 dbg(:a, :b) # [models/user.rb:22] a = 1 # [models/user.rb:22] b = 2 ``` This feature requires [binding_of_caller](https://github.com/banister/binding_of_caller) gem, but if it was found useful enough, maybe it could be possible to reimplement it without external deps? Optional identifiers together with file name and LOC info would make Ruby debugging much simpler. ---------------------------------------- Feature #20987: Add dbg - minimal debugging helper https://bugs.ruby-lang.org/issues/20987#change-111211 * Author: pawurb (Pawel Urbanek) * Status: Open ---------------------------------------- Hi. It's my first time contributing here, so I'm sorry in advance if I've mixed something up. I’m author of https://github.com/pawurb/dbg-rb gem. `dbg` method is inspired by Rust where it's built-in into std-lib (https://doc.rust-lang.org/std/macro.dbg.html). AFAIK in Ruby there's no simple mechanism to puts debug values together with caller info without using external dependencies. What’s more frustrating is that while `p nil` outputs `nil` to the std, `puts nil` prints a blank line, sometimes making debugging sessions confusing. I would like to propose adding a minimal `dbg` helper method to stdlib: ``` dbg("Hello world", [1, 2, 3]) # => [dir/file.rb:12] "Hello world" # => [dir/file.rb:12] [1, 2, 3] ``` `dbg` will produce verbose output together with informative file name and LOC info. I think that such built-in feature would be useful for many Ruby devs. My gem uses external dependencies, but I've came up with this barebones implementation: ``` def dbg(*msgs) loc = caller_locations.first.to_s matching_loc = loc.match(/.+(rb)\:\d+\:(in)\s/) src = if matching_loc.nil? loc else matching_loc[0][0..-5] end file, line = src.split(":") file = file.split("/").last(2).join("/") src = "[#{file}:#{line}]" msgs.each do |msg| puts "#{src} #{msg.inspect}" end nil end ``` ---Files-------------------------------- Screenshot 2024-12-27 at 00.00.23.png (81.5 KB) -- https://bugs.ruby-lang.org/

Issue #20987 has been updated by mame (Yusuke Endoh). This proposal was discussed in the dev meeting. @matz said that, while adding a new method or changing the default behavior of `Kernel#p` is unacceptable, some kind of switch could be considered to make `Kernel#p` output the filename. Several ideas for the switch were raised. * environment variable: `P=1` * using the existing $DEBUG mode: `ruby -d` * (ab)using a warning category: `ruby -W:p` * `puby` (another command; joke) Among these, the use of `-d` was favored. However, the $DEBUG mode is impractical in modern times. Every time an exception occurs, an error message is output (even if it is rescue'd). Many libraries (including rubygems) output error messages under the $DEBUG mode. @ko1 will do some research and see if it is practical by stopping the error message every time an exception occurs. He said he will make a separate proposal. One more thing, the current proposal seems to output only one parent directory and file name, "dir/file.rb", but it is arguable whether this is enough or not. It would be annoying to always use absolute paths, but it might be better to use paths relative to the current directory. ---------------------------------------- Feature #20987: Add dbg - minimal debugging helper https://bugs.ruby-lang.org/issues/20987#change-111391 * Author: pawurb (Pawel Urbanek) * Status: Open ---------------------------------------- Hi. It's my first time contributing here, so I'm sorry in advance if I've mixed something up. I’m author of https://github.com/pawurb/dbg-rb gem. `dbg` method is inspired by Rust where it's built-in into std-lib (https://doc.rust-lang.org/std/macro.dbg.html). AFAIK in Ruby there's no simple mechanism to puts debug values together with caller info without using external dependencies. What’s more frustrating is that while `p nil` outputs `nil` to the std, `puts nil` prints a blank line, sometimes making debugging sessions confusing. I would like to propose adding a minimal `dbg` helper method to stdlib: ``` dbg("Hello world", [1, 2, 3]) # => [dir/file.rb:12] "Hello world" # => [dir/file.rb:12] [1, 2, 3] ``` `dbg` will produce verbose output together with informative file name and LOC info. I think that such built-in feature would be useful for many Ruby devs. My gem uses external dependencies, but I've came up with this barebones implementation: ``` def dbg(*msgs) loc = caller_locations.first.to_s matching_loc = loc.match(/.+(rb)\:\d+\:(in)\s/) src = if matching_loc.nil? loc else matching_loc[0][0..-5] end file, line = src.split(":") file = file.split("/").last(2).join("/") src = "[#{file}:#{line}]" msgs.each do |msg| puts "#{src} #{msg.inspect}" end nil end ``` ---Files-------------------------------- Screenshot 2024-12-27 at 00.00.23.png (81.5 KB) -- https://bugs.ruby-lang.org/
participants (2)
-
mame (Yusuke Endoh)
-
pawurb (Pawel Urbanek)