Slide 1

Slide 1 text

Rubyで書かれた ソースコードを読む技術 2020-10-03 Kaigi on Rails fukajun

Slide 2

Slide 2 text

今日話すこと

Slide 3

Slide 3 text

今日話すこと Rubyで書かれたソースコード読んでいて 困ったときにぼくがやっていること

Slide 4

Slide 4 text

自己紹介

Slide 5

Slide 5 text

自己紹介 - @fukajun - 株式会社ロコガイドで働くサーバーサイドエンジニア - データ基盤、インフラ周りを担当 - ときどきRuby&Railsでの開発に参加 - Railsとの出会い - Arelが入る前、Rails 2.3 or 3 くらい - sendagaya.rb主催 with @tkawa - 毎週月曜日に勉強会を開催 - そろそろ350回を超える!? - キーボード - デフォルト => hhkb type-s => NiZ atom66 (沼回避)

Slide 6

Slide 6 text

アジェンダ

Slide 7

Slide 7 text

アジェンダ - どういう感じで読めないか? - それを乗り越えるためには? - 具体的な方法

Slide 8

Slide 8 text

どういう感じで読めないか?

Slide 9

Slide 9 text

- コードがどこにあるのかわからない - コードを読んだけど推測する動作に自信が持てない - コードの流れがわからない どういう感じで読めないか?

Slide 10

Slide 10 text

それを乗り越えるには?

Slide 11

Slide 11 text

それを乗り越えるには? Rubyやgemの便利な機能を使う => 実際にコードを動かす

Slide 12

Slide 12 text

具体的な方法について

Slide 13

Slide 13 text

コードを探すには? (検索編)

Slide 14

Slide 14 text

コードを探すには?(検索編) gemのインストール場所をRails.root配下に ⬇こちらのやり方はDEPRECATED (bundler 2.1〜) $ bundle config set path ‘vendor/bundle’ --local $ bundle install $ bundle install --path vendor/bundle

Slide 15

Slide 15 text

コードを探すには?(検索編) Rails.root 配下にgemをインストールしたら? - △遅い・終わらない - grep - ◯簡単・速い・便利 - ag(silver searcher) - rg(ripgrep) - ack

Slide 16

Slide 16 text

コードを探すには? (メソッド編)

Slide 17

Slide 17 text

コードを探すには?(メソッド編) Method#source_location 1 class Hoge 2 def run 3 end 4 end hoge = Hoge.new > hoge.method(:run).source_location => ["hoge.rb", 2] > hoge.method(:run) # Ruby2.7〜 => #

Slide 18

Slide 18 text

コードを探すには?(メソッド編) 例) Railsのソースコードを読むときに使ってみる ActiveRecord::Base.connectionの定義場所を調べる > ActiveRecord::Base.method(:connection).source_location => [".../gems/activerecord-6.0.3.3/lib/active_record/connection_handling.rb", 188] 1 # frozen_string_literal: true 2 3 module ActiveRecord 4 module ConnectionHandling ... 187 # to any of the specific Active Records. 188 def connection 189 retrieve_connection

Slide 19

Slide 19 text

具体的な動作について知るには?

Slide 20

Slide 20 text

具体的な動作について知るには? デバッガーをつかう - binding.irb (ruby標準) - binding.pry (pry gem) - byebug (byebug gem) From: .../photos/app/controllers/albums_controller.rb @ line 3 : 1: class AlbumsController < ApplicationController 2: def index => 3: binding.irb 4: end 5: end

Slide 21

Slide 21 text

具体的な動作について知るには? From: .../photos/app/controllers/albums_controller.rb @ line 3 : 1: class AlbumsController < ApplicationController 2: def index => 3: binding.irb 4: end 5: end irb(#):001:0> params => "albums", "action"=>"index"} permitted: false> ... irb(#):007:0> controller_name => "albums" irb(#):008:0> action_name => "index"

Slide 22

Slide 22 text

呼び出し元について知るには?

Slide 23

Slide 23 text

呼び出し元について知るには? - puts caller (ruby標準) - backtrace (byebug gemでデバッグ中) class AlbumsController < ApplicationController def index puts caller end end

Slide 24

Slide 24 text

呼び出し元について知るには? .../app/controllers/albums_controller.rb:4:in `index' .../actionpack-6.0.3.3/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action' .../actionpack-6.0.3.3/lib/abstract_controller/base.rb:195:in `process_action' .../actionpack-6.0.3.3/lib/action_controller/metal/rendering.rb:30:in `process_action' .../actionpack-6.0.3.3/lib/abstract_controller/callbacks.rb:42:in `block in process_action' .../activesupport-6.0.3.3/lib/active_support/callbacks.rb:135:in `run_callbacks' : 省略 : .../rack-proxy-0.6.5/lib/rack/proxy.rb:57:in `call' .../railties-6.0.3.3/lib/rails/engine.rb:527:in `call' .../puma-4.3.6/lib/puma/server.rb:713:in `handle_request' .../puma-4.3.6/lib/puma/server.rb:472:in `process_client' .../puma-4.3.6/lib/puma/server.rb:328:in `block in run' .../puma-4.3.6/lib/puma/thread_pool.rb:134:in `block in spawn_thread' ※byebug起動中にスタックトレースをたどるときは、 up/down (スタック階層を上下移動) frame n (スタック階層n番へ移動), list (コード表示), edit (エディタで開く)を利用すると便利です

Slide 25

Slide 25 text

gemのコードを読むときは?

Slide 26

Slide 26 text

gemのコードを読むときは? - gemのコードでも気にせず変更 - 動作を知るためのコードを直接埋め込んでいく - binding.irb、byebugなどのデバッガー - Method#source_location, caller - puts, p - ブレークポイントを利用してもできるけど...

Slide 27

Slide 27 text

変更したgemを 元に戻すには?

Slide 28

Slide 28 text

変更したgemを元に戻すには? bundle or gem pristine コマンドを使う - Gemfileにあるgemを全部 - bundle pristine - Gemfileにあるgem(extensionなしのみ)を全部 : 速い ※ - bundle exec gem pristine --all --no-extension - 変更したgemを覚えている場合 ※ - bundle exec gem pristine [GEMNAME] --no-extension ※extensionありではうまく動作しなかった

Slide 29

Slide 29 text

迷子にならないように するには?

Slide 30

Slide 30 text

迷子にならないようにする? - コードを読む目的を明確に - 例) - 複数の値をオプションに渡す区切り文字を知る - activestorageでS3を使ったときのkeyの変更可否 - 目的をどこかにメモする - メモをときどき振り返る

Slide 31

Slide 31 text

まとめ

Slide 32

Slide 32 text

まとめ - 困ったときはRubyやgemに助けてもらおう - 読む前/長期化しそうなとき目的を再確認しよう - デバッグ力の向上にもつながるかも

Slide 33

Slide 33 text

ロコガイドではソースコードを どんどん読んで、Ruby/Railsで一緒に楽しく 開発してくれる仲間を募集中です! 気になったら wantedly、@fukajun に連絡ください

Slide 34

Slide 34 text

ご視聴ありがとうございました。