Reputation: 13972
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....
Upvotes: 13
Views: 3180
Reputation: 121010
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).
Upvotes: 8