2020/03/29

pry 0.13.0 で後方互換性を保ちつつ history file の path を設定する

pry が 0.13.0 になった際、実行履歴ファイルの指定方法が変更になった事への対応。加えて後方互換もつけたログ。


pry の警告(ruby 2.7.0 + pry 0.12.2)

ruby 2.7.0 で pry 0.12.2 を起動すると、以下のような警告が出ていました。
<main>:1: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead
/usr/local/bundle/gems/pry-0.12.2/lib/pry/commands/whereami.rb:40: warning: in `eval'
<main>:1: warning: __LINE__ in eval may not return location in binding; use Binding#source_location instead
/usr/local/bundle/gems/pry-0.12.2/lib/pry/commands/whereami.rb:41: warning: in `eval'
<main>:1: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead
/usr/local/bundle/gems/pry-0.12.2/lib/pry/method/weird_method_locator.rb:88: warning: in `eval'
<main>:1: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead
/usr/local/bundle/gems/pry-0.12.2/lib/pry/method/weird_method_locator.rb:80: warning: in `eval'
view raw warning.txt hosted with ❤ by GitHub
私は怠惰なエンジニアなので、問題が発生するまでは様子見をする事にしました。


pry 0.13.0 Released

そして、2020/03/21 に pry の version 0.13.0 がリリースされました。
素晴らしい事に起動時に例の警告が出ません。 pry の開発陣に感謝ですね。
しかし、これでハッピーエンド、という訳にはいきませんでした。


Pry.config の変更

私は pry の history file の path を指定していました。具体的な設定は以下。
Pry.config.history.file = File.expand_path('path/to/history')
view raw old_config.rb hosted with ❤ by GitHub
0.12.2 はこの設定方法で問題ありませんでした。
しかし、 0.13.0 では設定方法が変わったようで、以下のように NoMethodError が発生します。
Error loading /root/.config/pry/pryrc: undefined method `file=' for #<Pry::History:0x00005624d9ce6298>
Did you mean? filter
/root/.config/pry/pryrc:1:in `__pry__'
view raw error.txt hosted with ❤ by GitHub
という事で設定方法を調べてみます。


設定方法探し

さて、指針も無く彷徨っても仕方が無いので、まずはそれらしい場所にあたりをつけます。
設定時、 Pry.config と書くので、 Config class か module あたりが無いか探します。
  • $ git grep Config
すると lib/pry/config.rb に Config class がありました。
流し読みしつつ、 history で検索します。そうすると history に関連するコードの集まりを見付けました。
さらに言えば history_file なる attribute がありますね。とてもとても怪しい。

Pry.config.history_file の値を pry で確認すると、今書き込まれている history の path でした。
変数が特定できたので、まずは path を代入してみます。 弾かれないか心配でしたが特に問題無し。
pryrc で Pry.config.history_file を設定すると、指定した path に history が書き込まれました。これで解決。

なお、history_file 辺りを blame して commit を確認する
`Pry.config.history.file` becomes `Pry.config.history_file`
とありました。なので調べた結論で正しそうです。


0.13.0 以前の history との互換性

さて、 pry 0.13.0 で history file の path を指定できました。

しかし bundler で gem を管理していると、バージョンが異なる pry が複数、なんてケースもあると思います。
幸い history file の中身は plain text なので、バージョン毎の違いは恐らくありません。
各 pry で同じ history の path を指定する事で、今まで通りバージョンに関わらず共通の history を参照できるはずです。
ということでバージョンが低い pry も考慮に入れた pryrc が以下。
@history_path = File.expand_path('path/to/history')
if Pry.config.respond_to?(:history_file=)
Pry.config.history_file = @history_path.clone
else
Pry.config.history.file = @history_path.clone
end
remove_instance_variable(:@history_path)
view raw new_config.rb hosted with ❤ by GitHub

  • respond_to? でバージョン確認
  • path は instance variable で一時的に定義して最後は消す
といった感じにしました。今の所は問題無く動作しています。