1

我正在逐步浏览使用 Sinatra 制作的hangman 应用程序的一些 Ruby 代码。具体来说,我正在查看post "/check" do下面的路径/功能。该函数的前两步是可预测的,即显示final_word变量,然后显示char_clicked变量,但随后调试器显示此 Hash.new

Hash.new {|hash,key| hash[key.to_s] if Symbol === key }

在继续使用该功能之前。我不明白为什么post "/check"此时要创建一个新的哈希。它在代码中并不明确,我也不清楚为什么会在幕后发生这种情况。我也在下面包含了正确的猜想方法,它在 `` 中被调用

final_word = session[:word]
(rdb:3) n
hangman.rb:79
char_clicked = params[:char_clicked]
(rdb:3) n
/Users/mm/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/sinatra-1.3.3/lib/sinatra/base.rb:916
Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
(rdb:3) n
hangman.rb:80
correct_guess = Game.correct_guess?(char_clicked, final_word)

检查路径

post "/check" do
  debugger
  final_word = session[:word]
  char_clicked = params[:char_clicked]
  correct_guess = Game.correct_guess?(char_clicked, final_word)

  if correct_guess
    session[:revealed_word] = Word.reveal(session[:revealed_word], char_clicked, final_word)
    session[:chars_left] = Word.chars_left(session[:revealed_word])
  else
    session[:incorrect_guesses] += 1
  end
  win = Game.win?(session[:chars_left], session[:incorrect_guesses])

  {:word => session[:revealed_word], :correct_guess => correct_guess, :incorrect_guesses => session[:incorrect_guesses], :win => win}.to_json
end

游戏correct_guess方法

def correct_guess?(char_clicked, final_word)
  final_word.include?(char_clicked)
end
4

1 回答 1

4

Sinatra 正在params为“无关访问”创建哈希(因此哈希键可以通过字符串或符号互换访问)。

Hash.new如果键不存在,则需要一个块来确定要返回的值。

例子:

>> sh = Hash.new
=> {}
>> sh["key"] = "value"
=> "value"
>> sh[:key]
=> nil

>> ih = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
=> {}
>> ih["key"] = "value"
=> "value"
>> ih[:key]
=> "value"

当您尝试访问params[:char_clicked]哈希块时,调试器会转储包含该块的完整行(此时实际上并未创建哈希):

h = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
debugger
h["invalid_key"]

->

sample.rb:5
h["invalid_key"]
(rdb:1) n
sample.rb:3
h = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }

当块在单独的行上时,更容易看到正在执行代码的哪一部分(即只是块):

h = Hash.new do 
  |hash, key| hash[key.to_s] if Symbol === key
end
debugger
h["invalid_key"]

->

sample.rb:7
h["invalid_key"]
(rdb:1) n
sample.rb:4
|hash, key| hash[key.to_s] if Symbol === key
于 2012-10-04T02:28:34.697 回答