Non-blocking IO & Maxima

Ok, here’s something that seems wierd. While writing some code to call
Maxima
(http://maxima.sourceforge.net/) from Ruby, I wrote the following:

class IO

Read a line without blocking. If there isn’t a line to be read,

return

nil.

def readline_nonblock
line = ‘’

begin
  char = read_nonblock 1 # A larger read would surely be more 

efficient.
while char != “\n”
line += char
char = read_nonblock 1
end
rescue Errno::EAGAIN
$stderr.puts ‘*** rescued EAGAIN’
line.reverse.each_byte { |c| ungetc© } # Replace partial line.
line = nil
rescue EOFError
line = nil
end

line

end

Yield once for every line recieved from readline_nonblocking, until

it

returns nil.

def each_nonblock
line = readline_nonblock
while not line.nil?
yield line
line = readline_nonblock
end
end
end

The wierdness is that this code behaves differently depending on whether
its
called from IRB’s toplevel or within a method. Here’s some expected
results:

irb(main):001:0> MaximaString = “maxima --batch-string=‘1+1;’”
=> “maxima --batch-string=‘1+1;’”
irb(main):002:0> ios = IO.popen MaximaString
=> #IO:0xb79d6068
irb(main):003:0> ios.each_nonblock { |line| puts line }
i i i i i i i ooooo o ooooooo ooooo ooooo
I I I I I I I 8 8 8 8 8 o 8 8
I \ +' / I 8 8 8 8 8 8 \-±’ / 8 8 8 ooooo 8oooo
`-|-’ 8 8 8 8 8
| 8 o 8 8 o 8 8
------±----- ooooo 8oooooo ooo8ooo ooooo 8

Copyright © Bruno Haible, Michael Stoll 1992, 1993
Copyright © Bruno Haible, Marcus Daniels 1994-1997
Copyright © Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright © Bruno Haible, Sam Steingold 1999-2003

Maxima 5.9.1 http://maxima.sourceforge.net
Using Lisp CLISP 2.38 (2006-01-24)
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
This is a development version of Maxima. The function bug_report()
provides bug reporting information.
(%i1) 1 + 1
(%o1) 2
=> nil

And now the unexpected:

irb(main):004:0> def foo
irb(main):005:1> ios = IO.popen MaximaString
irb(main):006:1> ios.each_nonblock { |line| puts line }
irb(main):007:1> end
=> nil
irb(main):008:0> foo
*** rescued EAGAIN
=> nil

WTF? If I use “ls” instead of “maxima --batch-string=‘1+1;’” then it
works it
both cases. So is this a problem with Maxima, Ruby, or my code?

(Oh, and I know that non-blocking IO isn’t required for the specific
example
above, but I’d still like it to work to be more general in code I
haven’t
posted. And to understand why this is happening.)

In article [email protected],
Jesse M. [email protected] writes:

WTF? If I use “ls” instead of “maxima --batch-string=‘1+1;’” then it works it
both cases. So is this a problem with Maxima, Ruby, or my code?

I think it is caused by that maxima is slower than ls.

Try “sleep 1; ls”.

It is impossible to read a line before a line is sent in
non-blocking manner.

On Saturday 23 June 2007 21:26, Tanaka A. wrote:

It is impossible to read a line before a line is sent in
non-blocking manner.

Ah, thats it, thanks. I wasn’t thinking about the delay between typing
lines
in IRB that gave it the time to execute…

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs