irb代替ツール Pryの応用編です。
この記事では、
で確認しています。
前回の復習
前回は、Pryのインストールをやって、Rails環境でも使えることをやりました。コマンドは、
tsubame.local{miyohide}% pry -r ./config/environment [1] pry(main)>
でOK。
スコープ変更の「cd」
Pryには、cdというコマンドがあります。スコープの変更というらしいのですが、動作を見たほうが早いでしょう。まず、起動した直後、Taskモデルに対するallメソッドを実行するには、
[3] pry(main)> Task.all => [#<Task id: 1, name: "hgehoge", created_at: "2012-03-25 10:41:18", updated_at: "2012-03-25 10:41:18">] [4] pry(main)>
とします。その後、cdコマンドを実行します。
[4] pry(main)> cd Task [5] pry(Task):1>
すると、次からは、Taskクラスの中にスコープが移動し、Task.allを実行したい場合は、allだけでOKとなります。
[5] pry(Task):1> all => [#<Task id: 1, name: "hgehoge", created_at: "2012-03-25 10:41:18", updated_at: "2012-03-25 10:41:18">] [6] pry(Task):1>
賢いのは、Task.allと打ってもOKなところ。
[6] pry(Task):1> Task.all => [#<Task id: 1, name: "hgehoge", created_at: "2012-03-25 10:41:18", updated_at: "2012-03-25 10:41:18">] [7] pry(Task):1>
cdはネストできるから、Task.firstの中に入ることも可能。
[10] pry(Task):1> cd first [11] pry(#<Task>):2> name => "hgehoge" [12] pry(#<Task>):2>
自分がどこにいるかを分からなかったら、selfやnestingを使えば良いです。
[12] pry(#<Task>):2> self => #<Task id: 1, name: "hgehoge", created_at: "2012-03-25 10:41:18", updated_at: "2012-03-25 10:41:18"> [13] pry(#<Task>):2> nesting Nesting status: -- 0. main (Pry top level) 1. Task 2. #<Task> [14] pry(#<Task>):2>
今のスコープから抜けたい場合は、exitを打つと、一段上に移ります。
[13] pry(#<Task>):2> nesting Nesting status: -- 0. main (Pry top level) 1. Task 2. #<Task> [14] pry(#<Task>):2> exit => #<Task id: 1, name: "hgehoge", created_at: "2012-03-25 10:41:18", updated_at: "2012-03-25 10:41:18"> [15] pry(Task):1> nesting Nesting status: -- 0. main (Pry top level) 1. Task [16] pry(Task):1> exit => Task(id: integer, name: string, created_at: datetime, updated_at: datetime) [17] pry(main)> nesting Nesting status: -- 0. main (Pry top level) [18] pry(main)>
デバッグに
これまでRailsアプリケーションのデバックでは主にputsを使っていたのですが、それもPryを導入することで卒業となりそうです。ソース内にbinding.pryと書くことで、そこで処理が止まり変数の確認ができます。実際にやってみましょう。
まずは、Gemfileの編集です。
gem 'pry', :group => :development
上の1行を追加して、bundle installすると完了です。
その後、止めたいところにbinding.pryを挿入すると良いです。例えば、以下はscaffoldで作ったControllerのindexメソッドのところに挿入してみました。
class TasksController < ApplicationController def index @tasks = Task.all binding.pry respond_to do |format| format.html # index.html.erb format.json { render json: @tasks } end end # 以下省略
後は、rails sでサーバを起動し、ブラウザでアクセスすると、コンソール上には次の表示が出ます。
tsubame.local{miyohide}% rails s [~/work/RailsSample/capybara/
=> Booting WEBrick
=> Rails 3.2.2 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2012-03-31 18:21:22] INFO WEBrick 1.3.1
[2012-03-31 18:21:22] INFO ruby 1.9.2 (2011-07-09) [x86_64-darwin11.1.0]
[2012-03-31 18:21:22] INFO WEBrick::HTTPServer#start: pid=1144 port=3000From: /Users/miyohide/work/RailsSample/capybara/todo/app/controllers/tasks_controller.rb @ line 6 in TasksController#index:
1: class TasksController < ApplicationController
2: # GET /tasks
3: # GET /tasks.json
4: def index
5: @tasks = Task.all
=> 6: binding.pry
7:
8: respond_to do |format|
9: format.html # index.html.erb
10: format.json { render json: @tasks }
11: end[1] pry(#
)>
例えば、@tasksの中を確認してみましょう。
[1] pry(#<TasksController>)> puts @tasks #<Task:0x007fd046d6d148> => nil [2] pry(#<TasksController>)> puts @tasks.inspect [#<Task id: 1, name: "hgehoge", created_at: "2012-03-25 10:41:18", updated_at: "2012-03-25 10:41:18">] => nil [3] pry(#<TasksController>)>
デバッグには強力に役立ちそうですね。
終了させるには、exit-allとすると処理が進みます。
[3] pry(#
)> exit-all
Started GET "/tasks" for 127.0.0.1 at 2012-03-31 18:21:33 +0900
Processing by TasksController#index as HTML
Task Load (0.2ms) SELECT "tasks".* FROM "tasks"
…(以下省略)
まとめ
個人的には、binding.pryが超便利。ま、putsデバックなんて邪道、ちゃんとテストコード書けよって言われそうですが、ま、いろいろありまして・・・^^;
参考
RailsCasts #280。新幹線内で動画見てたとき、binding.pryのところで思わず「これ、すげぇ」って声上げてしまいました。