From: Phlip Date: 2002-09-01T15:38:00+09:00 Subject: beating features out of popen Rubies: I downloaded and installed a command-line Mancala game: http://ibiblio.org/pub/Linux/games/strategy/mancala-1.0.0.tar.gz Being in C, it has only a console user interface, and an attempt at an xforms user interface. Yuch. So I feel like throwing a TkCanvas on top of it. But the first hurdle is to connect to the mancala executable via full duplex pipes. Yuch. My feeb attempt, and the Lapidary (sorry) testage for it are below my sig. It works (so far) but looks hideous. Yes, I tried popen3 - it simply projected twice as many bugs into the space. The fix I finally got working lets an exception throw in lieu of detecting "end of stream". Yuch. Does anyone have any tips how to crack the vault that is the POSIX "open" standard? -- Phlip http://andstuff.org/HarryPotter -- Why is the "Cheesy Horror Movie Channel" called "SciFi"? -- #!/usr/bin/env ruby require 'tk' require 'fcntl' require 'trace' require 'open3' class Mancala def initialize @canvas = nil @top = nil @boardString = nil end def makeCanvas @top = TkRoot.new { title "Mancala" } @canvas = TkCanvas.new (@top) { grid 'row'=>0, 'column'=>0, 'sticky'=>'nsew' background '#aaaaaa' width 800 height 600 } end def getBoardString return @boardString end def pipeMancala 'Did this have to be so fucking hard?' pipe = IO.popen( "mancala 0", "r+" ) pipe.close_write() pipe.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) @boardString = '' loop do begin # TODO feel a scrap of guilt about using exceptions # to define normal control flow. And about throwing # away the exception type contents = pipe.gets() rescue break end # print contents @boardString += contents break if @boardString.size() > 159 end # trace_{@boardString} end def destroy @canvas.destroy() if @canvas != nil end end ----8<------------------------------------- #!/usr/bin/env ruby require 'Lapidary/TestCase' require 'Lapidary/UI/GTK/TestRunner' require 'Lapidary/UI/Console/TestRunner' require 'mancala.rb' class TestMancala < Lapidary::TestCase def setup system 'killall mancala' # TODO yank this hack out @aBoard = Mancala.new() end def test_makeCanvas @aBoard.makeCanvas() # Tk.mainloop @aBoard.destroy() end def test_pipeMancala @aBoard.pipeMancala() bs = @aBoard.getBoardString() assert bs == ''' f: 4 | e: 4 | d: 4 | c: 4 | b: 4 | a: 4 0 -----+------+------+------+------+----- 0 a: 4 | b: 4 | c: 4 | d: 4 | e: 4 | f: 4 ''' # Move for player at top: ' end def tearDown puts 'tearing down' @aBoard.destroy() end end class TS_Mancala def TS_Mancala.suite() suite = Lapidary::TestSuite.new() suite.add TestMancala.suite() return suite end end def main # Lapidary::UI::GTK::TestRunner.run(TS_Mancala) Lapidary::UI::Console::TestRunner.run(TS_Mancala) end main # Tk.mainloop