Byebug breakpoint setting and continuation trouble - ruby-on-rails

I am trying to learn Byebug and am following the (https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md) and I am getting stuck with setting a breakpoint and continuing after the breakpoint is set. After I set the breakpoint for line 5 and run continue, Byebug quits the session. Can someone see what I am doing wrong?
$byebug hanoi.rb
[1, 10] in /Users/jackburum/ruby/byebug-testing/hanoi.rb
1: #
2: #
3: #
=> 4: def hanoi(n, a, b, c)
5: hanoi(n - 1, a, c, b) if n - 1 > 0
6:
7: puts "Move disk #{a} to #{b}"
8:
9: hanoi(n - 1, c, b, a) if n - 1 > 0
10: end
(byebug) break 5
Successfully created breakpoint with id 1
(byebug) continue
$byebug hanoi.rb
If I run the next command instead of continue, the same issue occurs...
[1, 10] in /Users/jackburum/ruby/byebug-testing/triangle.rb
=> 1: def triangle(n)
2: tri = 0
3:
4: 0.upto(n) { |i| tri += i }
5:
6: tri
7: end
8:
9: # if __FILE__ == $triangle.rb
10: # t = triangle(3)
(byebug) break 2
Successfully created breakpoint with id 1
(byebug) next
$

are you meaning to use next here? continue is the same control+d, and will continue to run your code until either another breakpoint is reached or the code ends.
I'm figuring that when you type continue, the rest of your script runs and the program exits because there isn't another breakpoint.
By the way, it might be worth trying the pry gem instead of byebug. Unlike byebug, copy-pasting multi-line code works in pry and there are a number of other useful features such as source-code browsing and syntax highlighting. Although it doesn't come with 'next' or 'continue' out the box, you can install the pry-byebug gem to get these.
Edit
From the additional info you've given, this seems to actually be the expected behavior here. Here's what you need to understand about breakpoints:
They will not follow a downward scope change. For example, say I've written a method like this:
def my_method
puts "my method started"
byebug
5.times { "do something in a loop" }
end
my_method()
puts "my method is done"
puts "the program will end now"
When you run the code with ruby myfile.rb, the code gets to line 6 before pausing on the breakpoint. Since the breakpoint is inside the method body, it won't be activated until the method is actually called.
What would happen if you typed next? Would you have to type it 5 times to get through the 5.times {} loop? The answer is no, and this is because there is a downward scope change into the iterator. In Javascript this "scope change" is more clear because you use the function keyword to show an anonymous function (and therefore a scope change). But in Ruby, blocks are actually syntactic sugar for Procs, which are anonymous functions and therefore introduce a scope change. I'm not sure of the exact reason, but moving into a method body also entails a downward scope change.
So when you press next, what actually happens is that it moves to the puts "my method is done" call. Although the byebug keyword is inside the method, to return to the scope of the method caller is an 'upward' scope change and is expected. Typing next again would move to the puts "my program will end now" line. Typing it again would get to the end of the code and exit the program.
If you needed to pause at each iteration in the loop, you could put the breakpoint inside the loop block i.e. 5.times { byebug }
To bring it back to your example - when you call your script with the byebug executable (i.e. byebug myprogram.rb), the initial scope is top-level. Typing next will skip over any functions or loops. I don't see this being practical for anything other than very small programs, so it's better to place the byebug keyword in your code and call the program with the ruby executable instead, i.e. ruby myprogram.rb
It's a small detail, but breakpoints are ignored when they are the last line in a program. To prevent this, put anything after the breakpoint, even something as simple as exit.
By the way, all this scope stuff applies to pry too as far as I'm aware.

Related

How to copy multiple lines of code into byebug?

byebug doesn't seem to be able to handle multiple lines of code.
Example
I put byebug into the controller, and the next lines of code are (these could be anything, just an example here):
payment_intent = Stripe::PaymentIntent.create({
payment_method_types: ['card'],
amount: #amount_minor_unit,
currency: #currency,
application_fee_amount: 123, # STODO
transfer_data: {
destination: #star.stripe_account,
},
})
But it does this:
If the code is edited so it's on one single line, it succeeds:
payment_intent = Stripe::PaymentIntent.create({payment_method_types: ['card'],amount: #amount_minor_unit,currency: #currency,application_fee_amount: 123, transfer_data: {destination: #star.stripe_account,},})
But this manual editing is extremely tedious. How can I make byebug accept multiple lines of code so that I can copy/paste directly from somewhere like a controller into the byebug-halted rails server?
Other ideas
After pressing ctrl+d in the console to exit byebug, then the browser errors, then I can copy code into the browser, but the same thing happens, where it accepts the code if it's all on one line:
..but otherwise errors with the same syntax error as above.
what works for me is Just copy all the code in one and paste it to the browser where we paste the link don't click enter. it will format it in one line. then just copy and paste in the byebug cli.
I use the gem pry-byebug and it has the behaviour you want, you can paste multiple lines of code without it executing right away.
https://github.com/deivid-rodriguez/pry-byebug
You can just add it to your gem file and set break points with binding.pry
The comments have already given you the answer, but I will formalize it here.
Instead of trying to copy and paste the line of code you want to execute, you can just use step to take a "step" through the code. Byebug's documentation gives you a list of commands you can use. Step will run your program one line at a time.
def index
byebug
init_item = {
a: "foo", b: "bar"
}
// omitted code
Entering the breakpoint above, init_item will be nil. The command step (or s) will advance the code one line, and after that, init_item will be initialized to what we specify.
Sometimes the byebug will enter a few lines "down", but using up (for going up the callstack) will let you navigate to the line you're interested in.
There's no need to copy-paste code into byebug, you can just step through it.

Breakpoints with pry-byebug don't trigger in the console

I'm trying to use pry and pry-byebug to step through the execution of some code in a Rails console. I started the console with
pry -r ./config/environment
I then set a breakpoint:
break Foo#bar
Then make a new Foo and call bar on it:
Foo.new.bar
I expected step into Foo#bar, but instead the method just executed normally.
Is there some way to get this workflow to work?
I found the answer: the debugger is not re-entrant. So you need to do this:
[1] pry(main)> binding.pry
[1] pry(main)> break Foo#bar
Breakpoint 1: Foo#bar (Enabled) :
6: def bar
7: end
[2] pry(main)> c # continue and exit the debugger we started on the first line
=> nil
[3] pry(main)> Foo.new.bar
Breakpoint 1. First hit.
Here is how I usually use pry-byebug
Add a call to binding.pry to the first line of the method Foo#bar
Run rails console
Call Foo.new.bar
You should see the pry REPL now
Hmm, when I use pry-byebug to debug my code I use in the following way:
First require the pry-byebug gem in the beginning of the coding
require 'pry-byebug'
def main # Do some coding
puts "Hello"
binding.pry # break point here
puts "World"
end
main
Then when running it my terminal will return enter irb mode and return:
> 3: def main
> 4: puts "Hello"
> 5:
> 6: binding.pry
> => 7: puts "World!"
> 8: end
>
> [1] pry(main)>
So the code indicates where I am right now, and from that point I could check every variable read before the breakpoint (on line 6). The breakpoint indicates the terminal have not yet read things after line 6, so if I had variables there, the terminal would not recognize them.
I could then type next, so binding.pry would jump to the next binding.pry point available or run through the whole code. Or I could simply type continue.
What is very important to remeber is to remove the require 'pry-byebug' and all the breakpoints lines before commiting your code, because we don't want the code to get stuck in those points, right? The user might not know how to deal with it :)
Hope it helped! First time trying to contribute to this awesome community :D

How to leave a method in pry

I'm using binding.pry in some Ruby code and I can't figure out how to get out of a long method that I don't want to be in.
I know n for next line and c for continue, but I can't get out of a method. I don't want to exit I just want to get out of the current method.
Conveniently, pry has a command called "help". Once issued it lists a number of things pry can do, including:
break Set or edit a breakpoint.
breakpoints List defined breakpoints.
continue Continue program execution and end the pry session.
finish Execute until current stack frame returns.
next Execute the next line within the current stack frame.
step Step execution into the next line or method.
It also supports aliases to other commands, which can be convenient:
!!! Alias for `exit-program`
!!# Alias for `exit-all`
$ Alias for `show-source`
? Alias for `show-doc`
# Alias for `whereami`
breakpoint Alias for `break`
breaks Alias for `breakpoints`
c Alias for `continue`
clipit Alias for `gist --clip`
f Alias for `finish`
file-mode Alias for `shell-mode`
history Alias for `hist`
n Alias for `next`
quit Alias for `exit`
quit-program Alias for `exit-program`
reload-method Alias for `reload-code`
s Alias for `step`
show-method Alias for `show-source`
According to the documentation the command you are looking for is f:
finish: Execute until current stack frame returns.
and shortcuts
if defined?(PryDebugger)
Pry.commands.alias_command 'c', 'continue'
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'
end

Ruby Debugger code for going into next line

I am working on ROR app , with ruby debugger. This is my code:
def render(d)
debugger
folder=d.folders
folders,empty_folders=check_empty_folder(folder)
c = cost(folders)
end
Now in console the break point at folders=d.folders . Now if i do next near around 30 times then it come to next line in this function folders,empty_folders after going through different ruby source file.
Is there any command I can simply go into next line of function in spite of source code.

Is it possible to step through a RoR application? or only debug using the debugging breakpoint?

I read that you can put a 'debugging' symbol in your RoR code, and then execution will Halt at that point and then you can then spit out anything into console to see the state of variables etc.
Is there a way to step though each line and follow the execution path?
There is documentation in the debugger itself. n and s are the commands that you are looking for.
(rdb:1) help
ruby-debug help v0.10.3
Type 'help <command-name>' for help on a specific command
Available commands:
backtrace delete enable help next quit show trace
break disable eval info p reload source undisplay
catch display exit irb pp restart step up
condition down finish list ps save thread var
continue edit frame method putl set tmate where
(rdb:1) help next
n[ext][+-]?[ nnn] step over once or nnn times,
'+' forces to move to another line.
'-' is the opposite of '+' and disables the force_stepping setting.
(rdb:1) help step
s[tep][+-]?[ nnn] step (into methods) once or nnn times
'+' forces to move to another line.
'-' is the opposite of '+' and disables the force_stepping setting.
(rdb:1)

Resources