Ruby Sinatra 存储变量

Ruby Sinatra storing variables

在下面的代码中,初始获取'/'包含一个表单,其动作是post'/'。当用户输入一个数字时,它应该被转换为一个将用于调用游戏的变量 class,为此我生成了另一个动作以在 get '/game' 处显示一个新表单。 post 方法中生成的变量未被存储。我怎样才能将在 post 和 link 中创建的变量都存储到 get '/game' 操作中?

require 'sinatra'
require 'sinatra/reloader'
@@count = 5
Dict = File.open("enable.txt")

class Game
   attr_accessor :letters, :number, :guess, :disp
   @@count = 5

   def initialize (number)
     letters = find(number) 
   end

   def find (n)
     words =[]
     dictionary = File.read(Dict)  
     dictionary.scan(/\w+/).each {|word| words << word if word.length == n}
     letters = words.sample.split("").to_a 
     letters
   end

   def counter
         if letters.include?guess
            correct = check_guess(guess, letters)
          else
           @@count -= 1
          end
   end
end

get '/' do 
   erb :index
end

post '/' do 
  n = params['number'].to_i
  @letters = Game.new(n) 
  redirect '/game' 
end

get "/game" do 


   guess = params['guess']
   letters = @letters
   if guess != nil
     correct = check_guess(guess, letters)
   end
   disp = display(letters, correct)          

   erb :game, :locals => {:letters => letters, :disp => disp}  

end



   def display(letters, correct)
     line = "__"
     d=[]
     letters.each do |x| 
       if correct == nil
         d << line
       elsif correct.include?x  
         d << x  
       else
         d << line
       end
     end
     d.join(" ")
   end 


   def check_guess(guess, letters)
     correct = [] 
     if guess != nil   
       if letters.include?guess
         correct << guess
       end
     end
     correct
   end

你不能这样做:

@letters = Game.new(n)

每次创建请求时,都会创建新的 Request 实例,因此 @letters 属性不再存在。

相当于

r = Request.new()
r.letters = Game.new()

r = Request.new()
r.letters  # not defined anymore!!

您可以使用 class 变量来实现您想要的效果

@@letters = Game.new(n)

尽管当您有多个用户时这将成为一场噩梦,并且只有在您只有一个 ruby 服务器进程时才有效。

一种更高级的方法是将 params['number'] 存储在会话 cookie 或数据库中。