Почему "block_given?" вернуть false в отладчике? (Работает правильно, когда не отлаживает) - PullRequest
2 голосов
/ 09 декабря 2011

При тестировании с отладчиком ruby ​​ block_given? выдает false , но все еще выполняет, может кто-нибудь объяснить мне, как он выполняется? Отладчик меняет контекст)? если да, то как найти текущий контекст.

Теперь вместо ruby-debug при использовании pry затем block_given? возвращает true .

def test
  debugger
  if block_given?
    yield(4)
  else
    puts "ss"
  end
end
test {|el| puts "#{el}" }

1 Ответ

3 голосов
/ 14 декабря 2011

Это похоже на ошибку в ruby-debug, в частности Kernel # binding_n , которая используется отладчиком.

Вам не нужно углубляться в чтение отладчика/ eval / print loop, чтобы увидеть ошибку.Вот пример неинтерактивного примера, заменив вызов debugger () на binding_n (0) :

require 'rubygems'; require 'ruby-debug'
Debugger.start
def test
  puts eval("block_given?", binding_n(0))
  if block_given?
    yield(4)
  else
    puts "ss"
 end
end
test {|el| puts "#{el}" }

У Pry, вероятно, нет этой проблемы, потому чтоон использует binding () , а не binding_n () .Конечно, это самый надежный.

В приведенном выше случае это явно выигрыш, поскольку binding () - это именно то, что нужно.Но, как бы ни был хорош Pry, он не может оценивать выражения в любом контексте стекового фрейма, кроме текущего (или самого последнего) стекового фрейма.

См. Также http://banisterfiend.wordpress.com/2011/01/27/turning-irb-on-its-head-with-pry/#comment-274 о различиях между Pry и отладчиком.например, ruby-debug.

Наконец, отмечу, что я пробовал это как в пропатченном отладчике MRI 1.9.2 * с трепановым отладчиком , так и rbx-trepanning для Rubinius 1,2-иш.

Они оба работают как положено.В обоих случаях эквивалент binding_n выполняется по-другому с большей помощью из среды выполнения Ruby.Это оставляет rb8-trepanning , в котором есть ошибка, потому что он также использует binding_n .

...