`binding.pry` против `pry`

В чем разница между вызовами pry и binding.pry? Например:

require 'pry'

class Bookshop
  def initialize(book)
    @books = []
    @hp = 'harry potter'
    lotr = 'lord of the rings'
    @books << @harry_potter
    @books << lord_of_the_rings
    @books << book
    binding.pry #OR pry
  end

  def print_all_books
    puts @books.join(', ')
  end
end

new_bookshop = Bookshop.new('the hobbit')
  • binding.pry дает мне доступ к переменной экземпляра @hp, локальным переменным lotr и методу экземпляра print_all_books.
  • pry дает доступ к переменным и методам экземпляра, но выдает NameError: undefined local variable вместо lotr.

Оба указывают на один и тот же контекст. Что здесь происходит? Есть ли случай, когда желателен вызов pry вместо binding.pry?


person Francio Rodrigues    schedule 21.12.2017    source источник
comment
binding — это специальный объект, в котором хранятся локальные переменные. При добавлении pry к объекту binding эти локальные переменные становятся доступными для отладчика REPL. Обратите внимание, что есть еще один способ сделать это: Pry.start(binding). Метод pry на самом деле определен в Object: см. здесь для получения дополнительной информации.   -  person max pleaner    schedule 21.12.2017
comment
Я проверяю это, и Pry.start(binding) эквивалентно binding.pry. Pry.start(binding) кажется более понятным. Спасибо! Я до сих пор не уверен, что делает только вызов pry.   -  person Francio Rodrigues    schedule 21.12.2017
comment
Метод pry определен для объекта, поэтому вы можете вызывать его для чего угодно: 1.pry например, хотя для этого нет причин. Когда вы вызываете его на binding, это делает доступными локальные переменные.   -  person max pleaner    schedule 21.12.2017
comment
Если это не дубликат, вы должны сделать свой комментарий ответом, @maxpleaner.   -  person Jim Stewart    schedule 21.12.2017


Ответы (1)


Повторяю то, что я сказал в комментариях.

Если вы посмотрите на источник метода (http://www.rubydoc.info/github/pry/pry/Object), он исправлен для Object, что означает, что вы можете вызывать его практически для чего угодно. Что бы вы ни вызывали, оно становится значением self в последующем REPL. pry, self.pry и Pry.start(self) делают одно и то же.

binding - это своего рода волшебная/сложная вещь, которая фиксирует "контекст" в определенном месте и делает эти локальные переменные доступными из других мест. Используя binding.pry или Pry.start(binding), вы гарантируете, что локальные переменные находятся в области REPL (как именно, я не могу сказать).

Вы также видите, что binding используется в других местах, где вы хотите ссылаться на локальные переменные в какой-то другой области. Например, чтобы оценить строку ERB, вы можете использовать ERB.new(string).result(binding).

person max pleaner    schedule 21.12.2017
comment
Спасибо за помощь. Эта статья также содержит полезную информацию и примеры по этому вопросу. - person Francio Rodrigues; 21.12.2017