Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Pry による REPL 駆動開発(2019-03-13)

482 views

Published on

Otemachi.rb #15 発表資料

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Pry による REPL 駆動開発(2019-03-13)

  1. 1. pry による REPL 開発について 2019/03/13 Tomoya Kawanishi エネチェンジチーフエンジニア
  2. 2. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 1自己紹介 Tomoya Kawanishi a.k.a cuzic エネチェンジ株式会社 チーフエンジニア エンジニア、積極採用してます! wantedly 経由でのご応募お待ちしております。 Ruby関西の中の人 みなさん、登壇お願いします! Otemachi.rb の中の人 ご参加お待ちしています。
  3. 3. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 REPL とは、pry とは REPL Read、 Evaluate、 Print、 Loop Lisp の関数名に由来して、REPL と呼ばれる Ruby だと irb でできることが REPL 詳細まだ決まっていないときに、いろいろ実験するときに使え る(詳しくはあとで) pry irb よりイケてる代替物 イケてるプラグインとかも使える pry-byebug pry-stack_explorer 2
  4. 4. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 よくある開発サイクル 開発速度 = (実装→失敗→調査→修正)のループの回転速度 よくある開発サイクル ①エディタ等で、機能を実装する ②ファイルを保存 ③動作を確認 ④うまく動かず、失敗する この変数は、Date型?Time型?String型? ハッシュのキーって、Symbol?文字列? 引数って、モデルのオブジェクト? id ? ⑤原因を調査する ⑥修正し、②に戻る 3
  5. 5. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 REPL 駆動開発 REPL 駆動開発の開発サイクル ①機能を実装したい箇所にまず binding.pry を仕込む ②うまく動作するように、REPL 上で試行錯誤する ③うまくいったものをエディタにコピーする ④実際に動かしてみる! ⑤最初からイイ感じに動作する! 4 REPL駆動開発で、試行錯誤のループを高速回転!
  6. 6. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 binding.pry とは binding.pry で、任意の場所で止めて、その場所の状態 を確認することができる さまざまな変数の値を調べることで、不具合の原因の調 査ができる 5 def index binding.pry # 処理内容 end
  7. 7. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 ?、show-doc、$、show-method ? や show-doc を使うとドキュメントを確認できる $ や show-method を使うとメソッドの定義を確認で きる 6 pry(main)> ? {}.values_at From: hash.c (C Method): Owner: Hash Visibility: public Signature: values_at(*arg1) Number of lines: 5 Return an array containing the values associated with the given keys. Also see Hash.select. h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } h.values_at("cow", "cat") #=> ["bovine", "feline"]
  8. 8. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 cd、ls 、TAB補完 cd でコンテキストを移動できる ls で、オブジェクトの持つメソッド、インスタンス変数 などを一覧で確認できる 候補となる単語をタブで補完できる 7 pry(main)> ls [] pry(main)> cd [] pry(#<Array>):1> ls pry(#<Array>):1> cd .. pry(main)>
  9. 9. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 exit!、!!!、exit-program binding.pry で調査しているときのあるある ループの内側で binding.pry を書く binding.pry のところで何度も何度も止められる ウザい 乱暴な方法だけど、 exit! を使うと、Ruby のプロセス を終了できる rails s の中でこれをすると、rails s が落ちる 8 pry(main)> exit! pry(main)> !!! pry(main)> exit-program
  10. 10. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 break break でブレイクポイントを設定できる ループの中で中断したいときなどは、 ① メソッドの先頭等で binding.pry を仕込む ② 条件付きでブレイクポイントを設定する ③ 調査、検証が終了すれば、ブレイクポイントを削除する というような、手順で作業するのがオススメ 9 pry(main)> break 10 # カレントファイルの 10行目にブレイクポイントを設定する pry(main)> break app/models/user.rb:15 # user.rb の 15行目にブレイクポイントを設 定する pry(main)> break 14 if provider.key == "tepco" # provider.key が tepco の場 合にのみ 14 行目で中断させる pry(main)> break # ブレイクポイントを一覧表示 pry(main)> break --delete 1 # ブレイクポイント#1 を削除
  11. 11. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 . と shell-mode shell-mode で、カレントディレクトリがプロンプトで 表示できる .echo hoge などとすると、シェルのコマンド入力とし て受け付けてくれる #{} による式展開が使えるので便利 10 pry(main)> filename = Rails.root + "db/schema.rb" pry(main)> .cat #{filename}
  12. 12. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 help pry のコマンドの全リストを確認できる 11 [1] pry(main)> help Help help Show a list of commands or information about a specific command. Context cd Move into a new context (object or scope). find-method Recursively search for a method within a class/module or the current namespace. ls Show the list of vars and methods in the current scope.
  13. 13. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 ls の高度な使い方 ls –m –G find オブジェクト名 そのオブジェクトのメソッドで find を含むものだけを表示 -G の引数として正規表現がつかえる 12 pry(main)> ls -m -G find User ActiveRecord::Querying#methods: find_by_sql find_in_batches find_or_create_by! find_each find_or_create_by find_or_initialize_by ActiveRecord::Core::ClassMethods#methods: find find_by find_by! initialize_find_by_cache ActiveRecord::Inheritance::ClassMethods#methods: finder_needs_type_condition? ActiveRecord::Base.methods: _find_callbacks _find_callbacks? find_by_statement_cache= _find_callbacks= after_find find_by_statement_cache? User.methods: find_by_statement_cache
  14. 14. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 pry-byebug pry-byebug でステップ実行ができる step と next は実行する行数を引数にとれる ユースケース 心当たりなく、変数の値が書き換わっている! 更新箇所を特定したい! ① 変数の書き換わる前、後の場所を特定する ② step 1000 などと実行し、変更があるかどうかを調べる ③ ②を繰り返し行い、2分探索などを実施し、変更箇所を特定する 13 pry(main)> step # 次のスコープの中に入る。(ステップイン) pry(main)> next # 現在のスコープで1行進む。(ステップオーバー) pry(main)> finish # 現在のスコープを抜ける(ステップアウト) pry(main)> continue # 次のブレイクポイントまで進む pry(main)> step 10 # ステップインで 10行進む pry(main)> next 10 # ステップオーバーで 10行進む
  15. 15. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 pry-stack_explorer pry-stack_explorer を使うと、呼び出し元にコンテキ ストを移動できる 呼び出し元の変数の値がどうなっているか確認できる ユースケース 意図せず before_save のフックが実行されてる! どこで、save が行われているか特定したい! 実行されているフックの中で、binding.pry を設定 show-stack で、どこで save が実行されてるか特定 14 pry(main)> show-stack # スタックのリストを表示 pry(main)> frame 10 # そのスタックにコンテキストを移動する pry(main)> up # そのメソッドの呼び出し元に移動 pry(main)> down # その行のメソッドを呼び出した先に移動
  16. 16. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 Tips: pry コマンドと名前が重複しているとき history という名前の変数の内容を binding.pry から 確認したい! eval するとうまくいく! 15 pry(main)> history # 入力履歴が表示される pry(main)> eval("history") # ローカル変数 history の内容が表示される
  17. 17. Otemachi.rb #15 発表資料 「pry による REPL 駆動開発について」 結びとして pry の機能は一度ちゃんと勉強するととても役立ちます。 私自身とても勉強になりました。 今回は、Ruby を前提とした説明でしたが、他言語( javascript 等)でも、REPL 駆動開発は役立ちます。 REPL駆動開発をすることで、ライブラリの仕様、仕様・ 実装について、思い込みで時間を浪費することで減り、 開発生産性がとても向上します。 また、懇親会等で感想を聞かせてください。 16
  18. 18. 17 ご清聴ありがとう ございました

×