Есть ли способ использовать нажатие клавиши, чтобы вызвать жуткий рубиновый камень?

Я просто думал о том, как здорово было бы запустить программу, а затем нажать клавишу, чтобы вызвать pry и debug. Может быть, есть камень, который динамически вставляет binding.pry во время выполнения, о котором я не знаю. Если этого не произойдет, как бы вы сделали нажатие клавиши binding.pry перед следующей строкой ruby ​​script, которая вот-вот будет выполнена?

Ответ 1

Предполагая ОС POSIX, вы можете попробовать добавить обработчик сигнала в свою рубиновую программу. Документация рубина даже дает пример вашего варианта использования:

.. ваш процесс может захватить сигнал USR1 и использовать его для переключения отладки (http://www.ruby-doc.org/core-2.1.3/Signal.html)

Signal.trap('USR1') do
  binding.pry
end

Затем, чтобы отправить сигнал:

kill -s SIGUSR1 [pid]

Изменить: более полный пример: application.rb

Мое наивное предложение выше потерпит неудачу с ThreadError: current thread not owner. Вот лучший пример с использованием глобального флага $debug.

#!/usr/bin/env ruby

require 'pry'

$debug = false
Signal.trap('USR1') do
  puts 'trapped USR1'
  $debug = true
end

class Application
  def run
    while true
      print '.'
      sleep 5
      binding.pry if $debug
    end
  end
end

Application.new.run

Это работает лучше всего, когда application.rb работает на переднем плане в одной оболочке, и вы отправляете сигнал SIGUSR1 из отдельной оболочки.

Протестировано в Mac OS 10.9.5. YMMV.