Reading from $stdin


A

Adrian Roskrow

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
 
Ad

Advertisements

R

Robert Klemme

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?

Do you actually redirect stdin to read from that device?
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

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
 
A

ara.t.howard

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.

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

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
 
A

Adrian Roskrow

Robert said:
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

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
 
A

Adrian Roskrow

Hmmm I need to read and digest this. Thankyou
in any case it looks like you're on the right track - welcome to ruby!

-a


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


Hmmm I need to read and digest this. Thankyou
 
R

Robert Klemme

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

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.
I like your code snippets and will try them out post hast.

Have fun!

robert
 
Ad

Advertisements

A

Adrian Roskrow

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
 
M

Martin Portman

Adrian said:
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

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

Adrian Roskrow

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
 
Ad

Advertisements

M

Marcel Ward

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

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

Top