##概要
ruby gemのコードの中身をデバッグしながら読む方法についてまとめます。
本記事では、binding.pryを埋め込んで任意の場所をデバッグできるところまでの設定部分をまとめます。settingslogicというGemが、ソースの中身も短くリーディング初心者にとっても優しそうだったのでサンプルとして選択しました。
環境
mac 11.2.3
ruby 2.7.2
bundler 2.1.4
手順
1.リーディング用のディレクトリを作成します。
mkdir gemcode_reading
2.ディレクトリ直下で、bundle initして、Gemfileを作成する。
bundle init
# gemcode_reading
# - Gemfile
3.デバッグ用のGemであるpryと、コードリーディングを行いたいGem(今回はsettingslogic)をGemfileに追加。
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "pry"
gem "settingslogic"
4.bundle installで必要なGemをインストール
bundle install
5.Gemを使用するためのスクリプトを準備。
#settings.rb
#対象のgemを読み込み
require "settingslogic"
#デバッグ用のpryを読み込み
require "pry"
# ソースと名前を指定すれば、設定yamlから任意の値を取得できるClassを作成。
# 取得部分のロジックを、今回ソースをデバッグするsettingslogicが担っています。
class Settings < Settingslogic
source "config/application.yml"
namespace "development"
end
p Settings.cool #{"saweet"=>"nested settings"}
p Settings.neat_setting #800
#config/application.yml
Custom: &defaults
cool:
saweet: nested settings
neat_setting: 24
development:
<<: *defaults
neat_setting: 800
test:
<<: *defaults
production:
<<: *defaults
6.Gemの内部の任意の箇所にbinding.pryを設置
#vendor/bundle/ruby/2.7.0/gems/settingslogic-2.0.9/lib/settingslogic.rb
class Settingslogic < Hash
def initialize(hash_or_file = self.class.source, section = nil)
#デバッグ
binding.pry
case hash_or_file
when nil
raise Errno::ENOENT, "No file specified as Settingslogic source"
when Hash
self.replace hash_or_file
else
file_contents = open(hash_or_file).read
hash = file_contents.empty? ? {} : YAML.load(ERB.new(file_contents).result).to_hash
if self.class.namespace
hash = hash[self.class.namespace] or return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}")
end
self.replace hash
end
@section = section || self.class.source # so end of error says "in application.yml"
create_accessors!
end
end
7.スクリプトを実行
bundle exec ruby settings.rb
8.デバッグ箇所の表示
95: def initialize(hash_or_file = self.class.source, section = nil)
=> 96: binding.pry
97: case hash_or_file
98: when nil
99: raise Errno::ENOENT, "No file specified as Settingslogic source"
100: when Hash
101: self.replace hash_or_file
102: else
103: file_contents = open(hash_or_file).read
104: hash = file_contents.empty? ? {} : YAML.load(ERB.new(file_contents).result).to_hash
105: if self.class.namespace
106: hash = hash[self.class.namespace] or return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}")
107: end
108: self.replace hash
109: end
110: @section = section || self.class.source # so end of error says "in application.yml"
111: create_accessors!
112: end
まとめ
デバッグ用に埋め込んだpryを起点にスクリプトを書き換えたりしながら、ソースの中身を探って行けます。今回は小規模なGemでしたが、ライブラリのコードの中身をしっかり把握するためにコードの重要な箇所は素早く正確に読めるようになりたいです。