TraceLocationというgemを使ってみた!

ツイッターを見ていたら、カルパスさんがコードリーディング用のgemを作ったという情報をgetしたので、早速試してみました!!1

 

以下はそのリポジトリです!

github.com

 

こちらのスライドで、どういう思いで作ったのか・どう使うのかについて書いてくださっております!!

speakerdeck.com

 

 

使ってみる!

railsを使って作成したブログアプリの中にTraceLocationを入れてみました!

 

①gemfileのなかに、gem 'trace_location' を書いてbundle installします。

 

②コンソールを立ち上げ、env = Rack::MockRequest.env_for('http://localhost:3000/api/stories') を実行します。
~/p/r/blog3 (master|✚2) $ rails c
Running via Spring preloader in process 3478
Loading development environment (Rails 5.2.2)
[1] pry(main)> env = Rack::MockRequest.env_for('http://localhost:3000/api/stories')
=> {"rack.version"=>[1, 3],
"rack.input"=>#<StringIO:0x00007fc82759a258>,
"rack.errors"=>#<StringIO:0x00007fc82759a4d8>,
"rack.multithread"=>true,
"rack.multiprocess"=>true,
"rack.run_once"=>false,
"REQUEST_METHOD"=>"GET",
"SERVER_NAME"=>"localhost",
"SERVER_PORT"=>"3000",
"QUERY_STRING"=>"",
"PATH_INFO"=>"/api/stories",
"rack.url_scheme"=>"http",
"HTTPS"=>"off",
"SCRIPT_NAME"=>"",
"CONTENT_LENGTH"=>"0"}

 

 

②TraceLocation.trace { status, headers, body = Rails.application.call(env) } を実行します。
[2] pry(main)> TraceLocation.trace { status, headers, body = Rails.application.call(env) }
Started GET "/api/stories" for at 2019-05-02 22:23:16 +0900
Cannot render console from ! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
(59.1ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
(5.4ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC

ActionController::RoutingError (No route matches [GET] "/api/stories"):

(pry):2:in `block in __pry__'
(pry):2:in `__pry__'
Created at /Users/hayashiyoshino/projects/rails-projects/blog3/log/trace_location-2019050222051556803399.log
=> true

 

 

/log/trace_location-2019050222051556803399.log ファイルを見にいきます。

すると、以下の画像のように、どのディレクトリに・ファイル名・何行目のメソッドが呼ばれたかが書かれているログがみれます!

gyazo.com

 

 

④ログの情報を元にソースコードを追ってみます。

/Users/hayashiyoshino/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.2/lib/rails.rb:39#application

を開いてみると、以下のようなメソッドが呼ばれておりました!

def application
@application ||= (app_class.instance if app_class)
end

 

次のログも同じように、

C /Users/hayashiyoshino/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.2/lib/rails/engine.rb:522#call

を開いてみると、以下のようなメソッドが呼ばれていることがわかりました!!

def call(env)
req = build_request env
app.call req.env
end

 

そしてcallメソッドの中で呼ばれている build_request メソッドは

C /Users/hayashiyoshino/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.2/lib/rails/application.rb:591#build_request

にあるようです!!

def build_request(env)
req = super
env["ORIGINAL_FULLPATH"] = req.fullpath
env["ORIGINAL_SCRIPT_NAME"] = req.script_name
req
end

 

 

 

感想その他

Rubymineのジャンプ機能を以ってしても迷子になる&人から解説してもらっても所々抜けてしまう自分にとって、とても有難いgemでした!!

コードを追いかけるべき順番と場所がこのようにこまかーーく出てくれているのは有難いです!!

迷子にならずコードを追えるのは非常に快適です!!

それと、以下のツイートでカルパスさんがおっしゃっていたように、bootsnapのログが沢山出るので、コードリーディングするときはbootsnapを呼ばれないようにするのが良さそうです!

 

コードリーディングやってゆきます!!