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