開発この記事はQiitaで書いた記事の転載です。技術系記事をはてなブログに書いていこうかなと思い、平行利用してみます。qiita.com本記事では、RailsでのWebアプリ開発で培ったREPLを使ったデバッグについて書きます。はじめに基本的にはRails利用者向けに書いていますが、Railsの機能を利用している具体的な箇所をご自身が利用されているフレームワークに当てはめれば、Railsを使っていない方でも役に立つかもしれません。話の内容としては以下の2本立てです。読んでいただければと思います。pry-byebugってなに?pryとbyebugという2つのGemを組み合わせて使えるようにするライブラリです。pryとは高機能なREPL(インタプリタとの対話環境)です。一方で、byebugはブレークポイントをコード上に打ってステップ実行をしていくデバッガです。pry-byebugはこの2つのGemを組み合わせ、byebugの機能を対話的に実行できるようにするものです。具体例を見せてくれcontrollerにbinding.pryを置いて実行してみます。endendここでconsoleを確認してみると以下のような画面が表示されます。pry-byebugはこの画面でプログラムと対話をしながら、デバッグをしていきます。"id"=>"16"}詳しい使い方はk0kubunさんの『今更聞けないpryの使い方と便利プラグイン集』におまかせします。REPL駆動デバッグをはじめようREPL駆動デバッグとは?私の造語で、REPLを使ってデバッグをしていくことを指します。1エラーメッセージと発生箇所だけで原因が特定できる単純なエラーであれば、対処は非常に楽です。バグやエラーの原因が発生箇所とは遠い彼方のモジュールにあったり、利用しているデータが壊れていることが原因だったり、はたまた複合的な要因だったりすることもあります。いう状況でのバグ対処では、まずは原因を切り分けて発生源を特定していきますよね。REPL駆動デバッグは、その作業をREPLを駆使してサッと解決してしまおうというものです。REPLで正常な挙動をチェックするバグを修正するためには、まずはゴールを確認する必要があります。そのため、「どこをどうすればいいのか」の情報を得る必要があります。最初にバグが発生している部分に焦点を当てて、本来あるべき正常な挙動と現在発生している異常な挙動を確認します。その部分をコード上で確認し、関係しているロジックのどの値がどうなっていればあるべき挙動になるのかを調査します。それさえできれば、その値が作られたロジックを遡って、挙動の確認を繰り返していくことで芋づる式にバグの原因にまでたどり着けるからです。2こうして、それぞれの部分であるべき動作を確認する作業では、コード上で思いつく限りの可能性を実験的に試していくことになると思います。そんなシチュエーションでは、小さな修正とコードの再実行を繰り返すことになります。そのため、コードを実行をしなおす時間すら惜しく思えてくるのではないかと思います。いうときにこそ、REPLが役に立ちます。以下は、REPLを使って正常な挙動を確認する具体例です。周辺のお店を紹介するサービスを運営しているという想定。LPのような特集ページで動的に生成しているリンク一覧が、仕様どおりの順番で並んでいないというバグがあった!という問題設定。...endまずはじめに、#generateの挙動を調べるため、メソッドの内部でbinding.pryをおきます。どこにおけばわからないときは、とりあえずメソッドの一番上に置くといいんじゃないかと思います。binding.pryで動作を止めた箇所で、正しい挙動を確認してみます。このメソッドの結果に影響を及ぼしていそうなところをチェックしましょう。内部で利用しているメソッド・関数ここで@arrangerの値が想定外のモノだったとします。その場合、それがどんな値になれば正常な挙動をするのかをチェックしてみましょう。StoreListLink::RecommendedArranger.new(...)のようにインスタンス変数や引数を直接書き換えて、挙動をチェックできます。このようにして、REPLを使って試行錯誤をすることで、原因の切り分けを手早く終わらせていきましょう。探索範囲を徐々に狭めて二分探索していく個別のクラスや関数の中でバグの原因を調査をするとき、まずは関数やクラスの結合点を調べると良いです。バグの原因が外にあるのか内から生まれたのかを確認して、探索範囲を絞っていきます。して、範囲を徐々に絞り込んでいくことで、関係のない箇所を調査して時間を浪費してしまうことを避けられます。以下に軽い具体例をあげます。クラスのイニシャライザ(#intialize)で代入されてる値が不正でないかをチェックしてみる、という例です。引数の時点で不正な値になっている場合は、現在のクラスの外にバグの原因があると推測できます。言えば、このクラスを利用している部分を調べる必要があるでしょう。引数に渡している値を調べて、バグの原因をさらに辿っていくと良いです。不正な値が入っているように見えなければ、そのクラス内でバグが作られている可能性が高いと判断できます。クラス内のロジックにバグが潜んでいて、それが原因で想定外の結果が生み出されていると言えそうです。そのため、バグの発生箇所で呼び出しているメソッドのロジックに関係している部分(プライベートメソッド、インスタンス変数など)を確認してみましょう。このように結合点を確認して、バグを調べていくことでより早くバグの原因にたどり着けるようになります。ソフトウェアエンジニアならば、普通にやっていることを言語化しただけかもしれませんね。ツッコミや提案があったらよろしくお願いします。REPL駆動開発にインスパイアされています。...、というわけではないですが、基本的にはこれで事足りるでしょう。それぞれ、オススメのお店順と需要の高い(ユーザー人気)順という意図で名前をつけている。ソフトウェア設計についてのポエム。はてなブログProWebエンジニアやってます。sudoを使えないLinuxのユーザがPackageを管理するための魔法の杖NAISTに入学してからもうすぐ3ヶ月が過ぎます。Base"とはなにか、そしてその可能性。NAISTに入学して一ヶ月が経ったので近況報告。退職をしてNAISTの修士課程に入学します月別アーカイブスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。