Reading from $stdin

Discussion in 'Ruby' started by Adrian Roskrow, Jan 17, 2007.

  1. Hi

    I need to read from a usb connected barcode reader and I thought ruby
    would be a good way to do it. I have written a quick program to read
    from the $stdin object but it just sits there and waits. Im very new to
    ruby so I have probably made a fundamental mistake. Can anyone see what
    I have done, or can anyone point me in the right direction or provide an
    example?

    Below is a simple bit of code

    #!/usr/bin/env ruby
    text = $stdin.read
    lines = text.split("\n")
    i = 1
    for line in lines do
    puts "#{i}. " + line
    i += 1
    end

    Adrian
     
    Adrian Roskrow, Jan 17, 2007
    #1
    1. Advertisements

  2. Do you actually redirect stdin to read from that device?
    I'd rather do

    $stdin.each do |line|
    printf "%4d %s", $stdin.lineno, line
    end

    or

    $stdin.each_with_index do |line, index|
    printf "%4d %s", index, line
    end

    HTH

    Kind regards

    robert
     
    Robert Klemme, Jan 17, 2007
    #2
    1. Advertisements

  3. Adrian Roskrow

    ara.t.howard Guest

    but this is __exactly__ what you told it to do?

    harp:~ > PAGER=cat ri 'IO#read'
    ---------------------------------------------------------------- IO#read
    ios.read([length [, buffer]]) => string, buffer, or nil
    ------------------------------------------------------------------------
    Reads at most _length_ bytes from the I/O stream, or to the end of
    file if _length_ is omitted or is +nil+. _length_ must be a
    non-negative integer or nil. If the optional _buffer_ argument is
    present, it must reference a String, which will receive the data.

    At end of file, it returns +nil+ or +""+ depend on _length_.
    +_ios_.read()+ and +_ios_.read(nil)+ returns +""+.
    +_ios_.read(_positive-integer_)+ returns nil.

    f = File.new("testfile")
    f.read(16) #=> "This is line one"

    so, in this case, you are reading until the end of stdin. you can enter eof on
    the command line (in *nix) with ctrl-d.
    afaikt your code works perfectly:

    harp:~ > cat a.rb
    #!/usr/bin/env ruby
    text = $stdin.read
    lines = text.split("\n")
    i = 1
    for line in lines do
    puts "#{i}. " + line
    i += 1
    end


    harp:~ > printf "42\n43\n" | ruby a.rb
    1. 42
    2. 43


    in any case it looks like you're on the right track - welcome to ruby!

    -a
     
    ara.t.howard, Jan 17, 2007
    #3
  4. Hi

    In answer to your question, no I don't redirct stdin, should I?

    I like your code snippets and will try them out post hast.

    Thanks

    Adrian
     
    Adrian Roskrow, Jan 17, 2007
    #4
  5. Hmmm I need to read and digest this. Thankyou

    Hmmm I need to read and digest what you have said Thankyou


    Hmmm I need to read and digest this. Thankyou
     
    Adrian Roskrow, Jan 17, 2007
    #5
  6. Well, if you don't the script will sit there and wait for you to enter
    something via keyboard. And you won't see any output from your version
    of the script until you press Ctrl-Z or whatever is the stream
    termination sequence on your operating system because the #read call
    reads all the way to the end of the stream. So, as Ara said, as long as
    there is no end #read cannot return and you don't see any output. The
    story is different with a line based implementation like mine.
    Have fun!

    robert
     
    Robert Klemme, Jan 17, 2007
    #6
  7. Well I have written a small script to read from stdin and guess what, it
    just sits and does nothing!! I guess I must of got it wrong! Here is
    small snip-it
    @number = $stdin.each_with_index do |line, index|
    printf "%4d %s", index, line
    end

    which is just the same as roberts code. I have a question, the bar code
    reader is connected to a usb port, do I still use stdin (or is this just
    for the keyboard?)

    how do I redirect the input to my code?

    I'm sorry to be asking basic questions but I am new to ruby.

    Adrian
     
    Adrian Roskrow, Jan 18, 2007
    #7
  8. each_with index reads one line at a time. A line needs to be
    terminated with an end of line character(s) before it can be read.

    Does your barcode reader insert end of line characters(s) at the end
    of the content of the barcode?

    I've used a usb barcode reader (in windows xp) and it does insert
    \r\n on the end of each sucessful read. Try the reader out in
    a text editor to see if it does. If it doesn't, you'll need to
    adopt a different approach than reading lines. Alternatively
    in the barcode driver, there may be an option to force it to emit
    end of line characters.

    If the barcode reader inserts chars into the editor, just like a keyboard,
    you shouldn't need to redirect the input at all. It should
    appear on $stdin.

    Martin.
     
    Martin Portman, Jan 18, 2007
    #8
  9. Hi

    I must be really stupid but I don't understand this at all, How does the
    usb scanner connect, to a text editor. I don't know how to do that. I
    understand how the scanner reads one line at a time, the end of the line
    being \r\n. What prompts the scanner to read another line, does the \r
    or \n do it? Barcode reader driver? there is no driver, have I got to
    write one?

    Adrian
     
    Adrian Roskrow, Jan 18, 2007
    #9
  10. Adrian Roskrow

    Marcel Ward Guest

    Hi Adrian,

    [what follows has nothing to do with Ruby; it concerns device setup]

    What you are talking about is in industry terms a "keyboard stuffer"
    device (also sometimes referred to as a "keyboard wedge" device).
    This is basically a device which injects characters into the input
    buffer stream. In the case of a USB device, it does this through
    software drivers. Either these drivers are installed automatically
    (e.g. on a plug-and-play O/S) or you must choose to install device
    drivers manually for your O/S.

    This is not the only way such a device may provide you with input
    data; for example, some wedge devices require that you access the
    incoming data by means of special driver interfaces and many permit
    two-way communication with the device. These kind of devices often do
    not come configured as keyboard stuffers by default.

    The easiest way to see if you have a keyboard stuffer is simply to
    plug it in, run up your favourite text editor and scan a barcode.
    Once it beeps to indicate successful read, you should see characters
    appear on your editor window. If nothing appears then your device is
    probably NOT configured as a keyboard stuffer.

    So, first things first, before you even start to run up Ruby, are you
    seeing digits on-screen when you do a valid scan?

    If so, does each barcode you scan appear as a sequence of digits on a
    separate line or do all the digits join together on the same line? If
    the latter then you will have to consult your device's manual to see
    how the terminating character can be set. Usually this is a simple
    matter of scanning the relevant setup barcodes from the manual pages.

    If you do not see anything at this stage then you won't see anything
    with $stdin either. Then it's time to seek out the device manual to
    see how to put it in keyboard stuffing mode.

    Hope that helps...
     
    Marcel Ward, Jan 18, 2007
    #10
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.