Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pry not stopping when called from a Ruby script that reads from stdin

Tags:

ruby

pry

I've created a console Ruby script that uses ARGF to load data from a file or stdin, that then calls Pry.

This works great when I pass a file in (Pry pauses) but fails (Pry doesn't stop and just exits Ruby) when I pass my data using stdin.

This is weird, anyone know why? I would like to pass data in via stdin and have Pry pause.

Behold, an example script:

require 'rubygems'
require 'pry'


def pry_it(str)
    binding.pry
end

pry_it(ARGF.read)

When I call this app with a file in ARGV I get my proper response - pry pausing

% bundle exec ruby pry_test.rb file.txt

From: /Users/wilcoxr/Development/json_pry/pry_test.rb @ line 8 Object#pry_it:

    6: def pry_it(str)
    7:
 => 8:  binding.pry
    9: end

[1] pry(main)>

Great! I can execute Pry commands all I want

When I try to use STDIN to send data into my tool:

% cat file.txt | bundle exec ruby pry_test.rb

From: /Users/wilcoxr/Development/json_pry/pry_test.rb @ line 8 Object#pry_it:

    6: def pry_it(str)
    7:
 => 8:  binding.pry
    9: end

[1] pry(main)>
% 

Look closely: note I'm back at my shell prompt, not pauses in IRB. Weird! I don't understand why I'm getting this behavior....

like image 752
RyanWilcox Avatar asked Sep 01 '15 14:09

RyanWilcox


People also ask

Why isn t binding Pry working?

To fix this just move the binding. pry command one line to the top and try to run your file again. If it still doesn't catch it, move the binding. pry command one more line to the top and keep doing this until your file catches the binding.

How do I use binding pry in Ruby?

The Ruby programmer can invoke the pry console during runtime by inserting the line 'binding. pry' wherever they would like to stop the program. When the interpreter hits the binding. pry, Pry will open a REPL session in the console, allowing you to test variables, return values, iterations, and more.


1 Answers

Try ARGF with simple:

require 'rubygems'
require 'pry'
binding.pry

Now IO operations are not covered internally by ARGF.read and it became evident what’s wrong here. ARGF is “glued” to STDIN, therefore whatever is being passed to STDIN goes directly to pry’s input.

I do not know exactly, what instruction in your file.txt forces pry to quit, but there is one.


UPDATE

It looks like if a Ruby script yields anything on stdin (e. g. through a pipe,) both $stdin and STDIN are set to this pipe, messing up pry’s “where am I run from” detection.

I came up with this not-so-elegant solution:

# read input from ARGF
text = ARGF.read

# prepare new stdin to satisfy pry
pry_fd_stdin = IO.sysopen("/dev/tty")
pry_stdin = IO.new(pry_fd_stdin, "r")

# load pry and cheat it with our stdio
require 'pry'
Pry.config.input = pry_stdin

binding.pry

This solution has some glitches (e.g. pry prompt is shown only after input).

like image 61
Aleksei Matiushkin Avatar answered Oct 22 '22 00:10

Aleksei Matiushkin