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

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....


Heh. This golf took me ten minutes to understand what drives this script bonkers.

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.


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

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 (eg pry prompt is shown only after input,) but the general idea is clear.

链接地址: http://www.djcxy.com/p/87654.html

上一篇: iOS9:自定义UIWindow使状态栏消失

下一篇: 当从一个从stdin读取的Ruby脚本中调用时,撬不停