PRY или IRB — перезагрузите класс и забудьте об удаленной функциональности

Если вы измените файл, а затем повторно загрузите его в pry или irb, он, кажется, подхватит любую НОВУЮ функциональность, которую вы добавили в этот класс, но не забудете о СТАРОЙ функциональности, которую вы удалили из этого класса.

Действия по воспроизведению:

  1. Создайте класс с одним методом - например. say_hello.
  2. Откройте PRY или IRB и load 'my_class.rb'
  3. Отредактируйте свой класс - удалите существующий метод и добавьте новый с другим именем - например. say_goodbye
  4. перезагрузить класс - load 'my_class.rb'

ОБА ваши методы теперь будут доступны. Я понимаю, почему это происходит - потому что ruby ​​позволяет вам повторно открывать классы для модификации, повторная загрузка вашего файла в основном просто повторно открывает существующую версию класса, который вы уже загрузили, вместо того, чтобы стирать память этого класса и определять класс снова с нуля.

Мой вопрос в том, как вы работаете с этим, кроме выхода и перезапуска PRY или IRB? Как просто сказать «полностью забыть мой предыдущий урок и перезагрузить этот файл с нуля»?

Спасибо!


person joshua.paling    schedule 22.11.2014    source источник


Ответы (3)


Вы можете использовать remove_const, чтобы удалить класс от его родителя, либо от Module, в котором он находится:

My::Module.send(:remove_const, :MyClass)

или из Object, если он не был объявлен внутри модуля:

Object.send(:remove_const, :MyClass)
person Uri Agassi    schedule 22.11.2014

Если вам не нужно выборочно перезагружать определенные модули, классы и т. д. и вы хотите сохранить свои локальные переменные, просто:

reload!
person VxJasonxV    schedule 19.10.2018

Пока вы находитесь в pry, вы можете использовать reset, и это сбросит среду.

Чтобы сбросить IRB, вы можете смотреть этот ответ, то есть exec($0)

Согласно сбросу, это exec 'pry' (+ некоторые вещи Pry). $0 в IRB кажется «irb», а в pry $0 — «pry».

$0 — это глобальная переменная, которая означает «работающую программу», так что это неудивительно.

Посмотрите исходный код в Pry для команды reset, я несколько удивлен, что они ссылаются на pry по имени, а не на эту хорошо известную переменную.

Вот код от Pry, который дает функциональность сброса и почему он увеличивает использование памяти.

class Command::Reset < Pry::ClassCommand
  match 'reset'
  group 'Context'
  description 'Reset the REPL to a clean state.'

  banner <<-'BANNER'
    Reset the REPL to a clean state.
  BANNER

  def process
    output.puts 'Pry reset.'
    exec 'pry'
  end
end

Это третья строчка от последней в этом списке.

Более чистый способ на самом деле вести хозяйство самостоятельно, как ответил Uri.

person vgoff    schedule 22.11.2014
comment
Вроде открывается другой Ruby (+ некоторые библиотеки). Это стоит вам еще ~ 80 МБ оперативной памяти. Это может быть ошибка в старой/Windows версии, но любой, кто пытается это сделать, должен знать об этом. - person Darek Nędza; 22.11.2014
comment
Что открывает другой Ruby и некоторые библиотеки? Сброс pry или exec ($ 0)? Любой, кто пробует то, что тоже должен знать об этом, @DarekNędza :) - person vgoff; 23.11.2014
comment
О верно. Я забыл о самом главном. Что ж, я проверил оба, Pry и IRB, и они оба открывают другой ruby.exe. Дополнительная информация для любознательных: reset это exec 'pry' (+ некоторые вещи Прая). $0 в IRB кажется "irb", а в подглядывании $0 это "pry". - person Darek Nędza; 24.11.2014
comment
Я не имел в виду exec($0) в pry, так как это не команда для reset pry, а сама команда reset. Хотя внутри он действительно может использовать exec($0). Так вы имели в виду, что в обоих случаях память увеличивается, когда вы делаете соответствующий сброс? Или вы хотите сказать, что если я загружу приложение само по себе, оно увеличится на этот объем памяти? - person vgoff; 25.11.2014
comment
Да, когда я ввожу exec($0) или reset память увеличивается. - person Darek Nędza; 26.11.2014