240

I'm using Pry with my Rails application. I set binding.pry inside a loop in my model to try and debug a problem. For example:

(1..100).each do |i|
  binding.pry
  puts i
end

When I type quit, it goes to the next iteration and stops again. Is there a way to step out of the loop so I don't have to type quit 100 times?

Currently the only way I know how to get out of it is to use CTRL+C and restart the application.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Ryan
  • 9,340
  • 5
  • 39
  • 42

10 Answers10

482

To exit Pry unconditionally, type

exit-program

Edit from @Nick's comment: Also works:

!!!
Qortex
  • 7,087
  • 3
  • 42
  • 59
Evandro
  • 4,868
  • 1
  • 14
  • 2
  • Though you'll obviously hit the binding straight away, using just `exit` will allow the program to keep running. – AJP Aug 17 '12 at 07:32
  • 1
    This did not work for me when running `rspec`. But CTRL-C, twice, did. – Eric Walker Jul 25 '13 at 17:48
  • 7
    on Mac OSX, pressing `Ctrl + C` twice will kill the Pry session, but will also effectively kill that terminal window: subsequent output is glitched such that I need to close that terminal tab and move to a new one. However `!!!` does not have this aggravating effect. – Topher Hunt Apr 01 '15 at 23:08
  • @Evandro You have no idea how this saved me! – Sri Harsha Kappala Apr 20 '16 at 06:30
  • Warning: If used inside an rspec test it can cause the test to falsely go green. Use the answer by @stebooks instead: `disable-pry` – Adamantish Jul 20 '16 at 18:08
  • In case somebody struck with * icon shown on pry command with Mac terminal , do single ctrl + C to start using Pry again – vikramvi Mar 22 '17 at 11:55
124

I use:

disable-pry

This will keep the program running, but will keep it from continuing to stop execution. This is especially helpful when you are debugging in the console.

stebooks
  • 2,317
  • 1
  • 20
  • 10
  • 15
    To re-enable (from the command line): ENV['DISABLE_PRY'] = nil – stebooks Jun 13 '14 at 13:33
  • 2
    i was not able to reenter pry after using disable-pry. Even after using ENV['DISABLE_PRY'] = nil – daslicious Oct 31 '14 at 18:06
  • 2
    To reenter pry, all you need to do is to set `ENV['DISABLE_PRY'] = nil` in your controller not in command line OR rails console. – Radix Jun 09 '15 at 05:56
  • This is the perfect one to use when you're using guard and just want it to stop running pry for that test run. It'll reset on the next test run. – BBonifield Aug 26 '15 at 19:33
41

To exit everything, use:

exit!

This should ignore all proceeding bindings.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Blake
  • 2,357
  • 3
  • 25
  • 35
  • 6
    This also kills the server at the same time. `exit-program` is still probably the best option if you don't want to restart the server. – Ryan Aug 14 '13 at 21:09
  • 3
    Just to clarify `exit-program` allows you to maintain your `rails server` session but seems to throw a `SystemExit` – Alan David Garcia Jan 14 '14 at 01:28
25

Triple exclamation (!!!) would do that.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Hahn
  • 367
  • 6
  • 6
  • This was the solution for me on OSX 10.11.4 (El Capitan), I did not try the `disable-pry` + `ENV['DISABLE_PRY'] = nil` combo but I did try `exit-program` which gave me a systemExit. This one just works. (On **rails** 3.2.22.2, **pry** 0.10.3 and **ruby** 1.9.3) – SidOfc Apr 28 '16 at 08:58
19

Use

disable-pry

To renable, add this to your controller

ENV['DISABLE_PRY'] = nil
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Chet3x16
  • 331
  • 2
  • 3
14

A binding.pry statement is exactly the same as a breakpoint in GDB. Such a breakpoint in GDB would be hit 100 times too.

If you only want the binding.pry to be hit once, for the first iteration of the loop, then use a conditional on the binding.pry like so:

(1..100).each do |i|
  binding.pry if i == 1
  puts i
end

You then exit the current session by just typing exit.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
horseyguy
  • 29,455
  • 20
  • 103
  • 145
2

Based on the two previous answers above:

Thank you guys! Your advices have helped me really a lot!

I just want to share a simple stupid trick, that I personally use to don't worry about the DISABLE_PRY environment variable all the time. Add this callback to the base controller ApplicationController of your project permanently. It would automatically re-enable PRY every time the disable-pry is called:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :reenable_pry

  private

  def reenable_pry
    ENV['DISABLE_PRY'] = nil
  end
end
zinovyev
  • 2,084
  • 1
  • 22
  • 32
2

Using gem pry-moves you can step out of loop using f (finish command)


example:

    42: def test
    43:   3.times do |i|
 => 44:     binding.pry
    45:     puts i
    46:   end
    47:   puts :finish
    48: end

[1] pry(main)> f
0
1
2

Frame: 0/1 method
From: playground/sand.rb:47 main

    42: def test
    43:   3.times do |i|
    44:     binding.pry
    45:     puts i
    46:   end
 => 47:   puts :finish
    48: end
Daniel Garmoshka
  • 5,849
  • 39
  • 40
2

press 'q' and you will see just like this

[1] pry(#<AlbumsController>)>

type

exit

this one word will do, if not:

control + c
Heartless Vayne
  • 904
  • 1
  • 8
  • 18
0

If you just need to debug one iteration, you can just raise error, escape guarantee :

(1..100).each do |i|
  binding.pry
  raise
  puts i
end

Or with condition :

(1..100).each do |i|
  if i == 50
    binding.pry 
    raise
  end
  puts i
end
Maxime Boué
  • 648
  • 7
  • 10