2014-04-30 90 views
1

我知道Ruby中不鼓勵使用全局變量,但這是我被要求做的事情,所以你只需要在這裏跟我一起去。我有一個遊戲,通過STDOUT成功地將消息輸出到命令窗口。我的任務是修改類,以便消息不僅顯示到STDOUT通道,而且寫入緩衝區。當我在文件末尾添加一個額外的Sinatra方法時,緩衝區顯示在瀏覽器中(即localhost:4567)。將消息發送到Ruby中的全局緩衝區

因此,如果使用調用的Sinatra gem,從命令窗口運行spec.rb,除了命令窗口之外,還應該在Web服務器中顯示消息。但我不知道從哪裏開始輸出我的消息到緩衝區。

我很確定這有一個非常簡單的答案,但我對Ruby的知識並不是很好。我的想法是我需要爲每個活動添加一行,將每個活動的輸出連接到全局變量$ buffer,但我該怎麼做?顯然,在這之後,我需要編寫一個Sinatra方法,在Web瀏覽器中顯示全局變量的內容。

希望是有道理的。

我有兩個文件,spec.rb和gen.rb.這是到目前爲止我的代碼:

spec.rb

require "gen.rb" 

module ImpossibleMachine 
    # Input and output constants processed by subprocesses 
    DOWN_ARROW = 1 
    UP_ARROW = 2 
    RIGHT_ARROW = 3 
    REPEAT_ARROW = 4 
    END_PROCESS = 5 
    START_CURRENT = 6 

    # RSpec Tests 
    describe Game do 
     describe "#start The impossible machine game" do 
      before(:each) do 
       @process = [] 
       @output = double('output').as_null_object 
       @game = Game.new(@output) 
      end 
      it "sends a welcome message" do 
       @output.should_receive(:puts).with('Welcome to the Impossible Machine!') 
       @game.start 
      end 
      it "sends a starting message" do 
       @output.should_receive(:puts).with('Starting game...') 
       @game.start   
      end 
      it "should perform lifts_lever_turns_wheel activity which returns REPEAT_ARROW" do 
       @output.should_receive(:puts).with("Input: #{UP_ARROW}, Activity: Heave_ho_squeek_squeek") 
       @process[1] = @game.lifts_lever_turns_wheel(UP_ARROW) 
       @process[1].should == REPEAT_ARROW 
      end 
      it "should perform turns_tap_on_pulls_down_seesaw activity which returns DOWN_ARROW" do 
       @output.should_receive(:puts).with("Input: #{REPEAT_ARROW}, Activity: Drip_drip_creek_creek") 
       @process[2] = @game.turns_tap_on_pulls_down_seesaw(REPEAT_ARROW) 
       @process[2].should == DOWN_ARROW 
      end 
      it "should perform pulls_down_seezaw_starts_current activity which returns START_CURRENT" do 
       @output.should_receive(:puts).with("Input: #{DOWN_ARROW}, Activity: Creek_creek_buzz_buzz") 
       @process[2] = @game.pulls_down_seezaw_starts_current(DOWN_ARROW) 
       @process[2].should == START_CURRENT 
      end 
      it "should perform starts_current_pushes_grove activity which returns RIGHT_ARROW" do 
       @output.should_receive(:puts).with("Input: #{START_CURRENT}, Activity: Buzz_buzz_pow_wallop") 
       @process[3] = @game.starts_current_pushes_grove(START_CURRENT) 
       @process[3].should == RIGHT_ARROW 
      end 
      it "sends a finishing message" do 
       @output.should_receive(:puts).with('...Game finished.') 
       @game.finish    
      end 
     end 
    end 
end 

gen.rb

require 'sinatra' 
$buffer = "" 

# Main class module 
module ImpossibleMachine 
    # Input and output constants processed by subprocesses. MUST NOT change. 
    DOWN_ARROW = 1 
    UP_ARROW = 2 
    RIGHT_ARROW = 3 
    REPEAT_ARROW = 4 
    END_PROCESS = 5 
    START_CURRENT = 6 

    class Game 
     attr_reader :process, :output 
     attr_writer :process, :output 

     def initialize(output) 
      @output = output 
      puts "[#{@output}]" 
     end 

     # All the code/methods aimed at passing the RSpect tests are below. 

     def start 
      @output.puts'Welcome to the Impossible Machine!' 
      @output.puts'Starting game...' 
     end 

     def lifts_lever_turns_wheel(input) 
      @input = input 
      @output.puts 'Input: 2, Activity: Heave_ho_squeek_squeek' 
      return REPEAT_ARROW 
     end 

     def turns_tap_on_pulls_down_seesaw(input) 
      @input = input 
      @output.puts 'Input: 4, Activity: Drip_drip_creek_creek' 
      return DOWN_ARROW 
     end 

     def pulls_down_seezaw_starts_current(input) 
      @input = input 
      @output.puts 'Input: 1, Activity: Creek_creek_buzz_buzz' 
      return START_CURRENT 
     end 

     def starts_current_pushes_grove(input) 
      @input = input 
      @output.puts 'Input: 6, Activity: Buzz_buzz_pow_wallop' 
      return RIGHT_ARROW 
     end 

     def finish 
      @output.puts'...Game finished.' 
     end 
    end 
end 

# Main program 

module ImpossibleMachine 
    @process = [] 
    g = Game.new(STDOUT) 

    # All code added to output the activity messages to the command line window is below. 

    g.start 
      @process[0] = g.lifts_lever_turns_wheel(2) 
      @process[1] = g.turns_tap_on_pulls_down_seesaw(@process[0]) 
      @process[2] = g.pulls_down_seezaw_starts_current(@process[1]) 
      @process[3] = g.starts_current_pushes_grove(@process[2]) 
    g.finish 
end 

# Any sinatra code added to output the activity messages to a browser should be added below. 



# End program  
+1

調查IO和StringIO:'g = Game.new(my_special_io)'。 –

+0

你知道'rspec'是用於測試的,而Sinatra是一個網絡服務器,它們並不在一起(除非你是_testing sinatra_,在這種情況下,沒有瀏覽器......) –

回答

2

設法讓這個工作幾小時後! 在頂部加入/調整爲:

require 'stringio' 
$buffer= StringIO.new 
主程序

g = Game.new($buffer) 
g.start 
@process[0] = g.lifts_lever_turns_wheel(2) 
etc...... 
g.finish 
puts $buffer.string #this sends it to stdout 

然後就在西納特拉編碼的底部也將使用$ buffer.string添加

可能不是最好或最聰明的方法,但它使用他們想要的全局緩衝區,並將其獲取到sinatra和cmd行。

+0

謝謝克萊爾!你是英雄 – samgbelton

+0

出於興趣,你的程序是一個互動遊戲,還是隻是打印輸出到瀏覽器?我只是沒有看到這個應用程序的重點。 – ClaireB

+0

我同意,我的打印輸出。這是我唯一擔心的事情,或許它需要互動。我認爲,因爲目的是爲了TDD,所以它不是必需的。 – samgbelton

1

我想你可能只是在你的主程序建立某種形式的緩衝對象並在遊戲中傳遞它,就像你通過STDOUT一樣。然後你可以在遊戲中的傳入對象上調用寫入方法。

相關問題