Rubyコードのデバッグ時に便利なPryですが、これをRSpec内から呼び出した場合、プロンプトが非常に長くなってしまい、不便なときがあります。
例えば以下のようなexample内でPryを呼び出すと、
module Gemologist
class Gemfile
describe Dependency do
describe '#version_specifiers' do
context 'when multiple specifiers are passed' do
it 'replaces the existing specifier with the passed specifiers' do
binding.pry
end
end
end
end
end
end
Pryのプロンプトに呼び出し元でのself
のクラス名が表示され、こんな感じになってしまいます。
[1] pry(#<RSpec::ExampleGroups::GemologistGemfileDependency::VersionSpecifiers_2::WhenMultipleSpecifiersArePassed>)>
これは、RSpecが各example groupクラスを動的に生成し、その際にdescribe
やcontext
に渡した説明文からクラス名を自動生成しているためです1。この機能自体はデバッグ時に助かることもありますが、上記のようにPryのプロンプトとの相性は悪いですね。
そこで、この長すぎるプロンプトを省略することにします。Pryのプロンプトは~/.pryrc
に設定を記述することでカスタマイズできるため、Pryを呼び出したコンテキストでのself
がRSpec::Core::ExampleGroup
のサブクラスのインスタンスだった場合は、RSpec::Core::ExampleGroup
と表示するように変更します。
Pry.config.prompt = Pry.config.prompt.map do |default_proc|
proc do |target_self, nest_level, pry|
# Use RSpec::Core::ExampleGroup instead of auto-generated long example group class name.
if defined?(RSpec::Core::ExampleGroup) && target_self.is_a?(RSpec::Core::ExampleGroup)
target_self = RSpec::Core::ExampleGroup
end
default_proc.call(target_self, nest_level, pry)
end
end
Pry.config.prompt
にはProc
インスタンスが2つ含まれた配列をセットする必要があります。今回の場合、カスタマイズしたい挙動以外に関してはデフォルトのプロンプトを引き継ぎたかったため、元々のPry.config.prompt
の配列の要素をそれぞれラップする形でカスタマイズを行いました。
上記のように~/.pryrc
を編集後、RSpec内で再度Pryを呼び出すと、プロンプトは以下のようになります。
[1] pry(RSpec::Core::ExampleGroup)>
-
説明文からのクラス名自動生成はRSpec 3.0.0から。それ以前は
RSpec::Core::ExampleGroup::Nested_2
のように連番で名前を生成していた。 ↩