0

我正在从“Programming ruby​​ 1.9”中学习 ruby​​。我正在学习使用 ruby​​-debug,所以我可以理解下面发生的事情。我使用 ruby​​mine,因为它集成了 ruby​​-debug19 或类似的东西(它说我没有 gem 并安装它)。这是问题,我能够单步执行代码并探索变量和堆栈。但是,当它到达 a 时for i in 0...5,调试器会说

堆栈帧不可用

我知道 ruby​​ 很少使用 for 循环,但我仍然想知道是否通过 for 循环进行调试。

代码:

    raw_text  = %{
The problem breaks down into two parts. First, given some text as a
string, return a list of words. That sounds like an array. Then, build a 
count for each distinct word. That sounds like a use for a hash---we can 
index it with the word and use the corresponding entry to keep a count.}

word_list = words_from_string(raw_text)
counts    = count_frequency(word_list)
sorted    = counts.sort_by {|word, count| count}
top_five  = sorted.last(5)

for i in 0...5            # (this is ugly code--read on
  word = top_five[i][0]   #  for a better version)
  count = top_five[i][1]
  puts "#{word}:  #{count}"
end
4

1 回答 1

2

如果您查看 Ruby 语言规范(第 91 页的第 11.5.2.3.4 条),您会看到

for i in 0...5
  word = top_five[i][0]
  count = top_five[i][1]
  puts "#{word}:  #{count}"
end

是语法糖

(0...5).each do |i|
  word = top_five[i][0]
  count = top_five[i][1]
  puts "#{word}:  #{count}"
end

除了没有为块创建新的变量范围。因此,代码 withfor将被翻译成代码 witheach并执行,就好像它是这样编写的,除了for循环中使用的变量泄漏到周围的范围内。

换句话说:for实际执行each没有为 block 分配新的堆栈帧。所以,错误信息是完全正确的:有一个块调用,但不知何故没有为该块调用分配堆栈帧。这显然会使调试器感到困惑。

现在,有人可能会争辩说这是一个错误,for循环应该在调试器中得到特殊处理。我猜到目前为止,没有人费心修复这个错误,因为没有人使用for循环,正是因为它们将变量泄漏到周围的范围中,并且完全等同于没有的惯用语each

“泄漏变量”是什么意思?看这里:

(1..2).each do |i|
  t = true
end

i
# NameError: undefined local variable or method `i' for main:Object

t
# NameError: undefined local variable or method `t' for main:Object

for i in 1..2
  t = true
end

i
# => 2

t
# => true
于 2012-09-19T13:43:59.393 回答