23.09.2009Получение irb-консоли в среде приложения
Задача
Допустим, есть приложение, написанное на руби. У него есть основной процесс и есть тесты, которые так или иначе загружают объекты приложения.
Хочется получить доступ в среду приложения в виде irb-консоли, чтобы вручную взаимодействовать с объектами и изменять данные. По типу script/console в rails.
Решение
Как большинство подобных решений, необходимость возникает, когда замечаешь себя за повторением одного и того же набора действий множество раз:
irb
require ...
require ...
...
Раз уж мы захотели как в рельсах, то следует предположить, что окружение нашего приложения загружается одним файлом. Например, config/environment.rb. Это будет первым упрощением многократно повторённого процесса.
Теперь сам файл script/console:
#!/usr/bin/env ruby
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), ".."))
libs = " -r irb/completion"
libs << " -r pp" # специально для консоли автоподставнока и pretty print
libs << %( -r "#{APP_ROOT}/config/environment.rb")
ENV["APP_ENV"] = "console" # пример того, как сообщить приложению, что оно в консоли
exec "irb #{libs} --simple=prompt"
Здесь стоит сделать два акцента:
- Для сообщения приложению, что оно запущено в консоли, мы использовали волшебный хэш ENV. К нему потом можно обратиться внутри config/environment.rb и сделать что-то по-другому.
- Для запуска консоли мы использовали Kernel.exec, который не просто выполняет системную команду, но и передаёт ей управление, заменяя текущий процесс.
Теперь, если сделать наш файл запускаемым, будет как в сказке:
chmod +x script/console
Я хочу, чтоб эта песня, эта песня не кончааалась
Если есть приятные библиотеки, которые хочется подключать при каждом запуске irb. А так же, если хочется сохранять историю команд консоли при выходе. То следует воспользоваться мощью ~/.irbrc. Создайте этот файл («~» -- это $HOME, на всякий случай) и напишите в него:
require 'pp' # pretty print
require 'irb/completion' # автоподстановка
require 'irb/ext/save-history' # сохранение истории
ARGV.concat [ "--readline", # не пробовал без readline
"--prompt-mode", "simple" ] # --simple-prompt
IRB.conf[:SAVE_HISTORY] = 25 # сколько сохранять
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history" # куда сохранять