序
rubyのコードを読んでいるときに
- implicitな部分についての知識が足りなさすぎる
- 複雑すぎてよくわからない
ときはデバッガを使います。
しかし、メソッドにstep inしたいのに、そのメソッドの引数だと思っていた記述が実はまたべつのメソッド呼び出しで、コールツリーがよくわからなくなったりすることがまれによくありました。
そんなときに、class Method
に生えている source_location メソッドを使えば良いことにようやく思い至ったのでメモしておきます。
破
rspec 実行時、 ActiveSupport::Cache::RedisCacheStore
で使われるredis clientをモックに差し替えようとしたが、with
というメソッドが無くて落ちてしまう原因を調査する例。
345行目の redis.with で method_missing になる。
redis の gem を見ても with
は定義されていないっぽい。
なんだろう。
From: /bundle/gems/activesupport-6.0.3.2/lib/active_support/cache/redis_cache_store.rb:344 ActiveSupport::Cache::Strategy::LocalCache#read_entry:
339: # Store provider interface:
340: # Read an entry from the cache.
341: def read_entry(key, **options)
342: failsafe :read_entry do
343: binding.pry
=> 344: raw = options&.fetch(:raw, false)
345: deserialize_entry(redis.with { |c| c.get(key) }, raw: raw)
346: end
347: end
348:
349: def read_multi_entries(names, **options)
モック差し替えをやめ、再実行して、ソースを表示してみる。
[1] pry(#<ActiveSupport::Cache::RedisCacheStore>)> redis.method(:with).source
=> " def with\n yield self\n end\n"
なんだこのメソッド。
そんなとき source_location
!
[2] pry(#<ActiveSupport::Cache::RedisCacheStore>)> redis.method(:with).source_location
=> ["/bundle/gems/activesupport-6.0.3.2/lib/active_support/cache/redis_cache_store.rb", 24]
ConnectionPoolLike
をincludeしてRedis
にパッチをあてることで、使い勝手を揃えているのかぁ。
モックで差し込むredis clientにも ConnectionPoolLike
をincludeしないとだめかなぁ。
ActiveSupportの実装が変わったら、ちゃんと追従できるかなぁ。
みたいな。
Q
いろんなところでクラスが開かれて動作を変えられちゃうと、ソースを読むだけだと気が付きにくいこともありますよね。
完。