SlideShare a Scribd company logo
kiev.rb #2

kiev

#2
.rb

Debugging on Rails
Mykhaylo Sorochan
Contents
Debugged application
Sample app for the Ruby on Rails Tutorial (Rails 4)
https://github.com/railstutorial/sample_app_rails_4
debugger
gem 'debugger'
debugger - call debugger
config - .rdebugrc
Debug location
UserController#show

def show
@user = User.find(params[:id])
debugger
@microposts = @user.microposts.paginate(page: params[:page])
end
Debugger commands
(rdb:9) help
ruby-debug help v1.6.2
Type 'help <command-name>' for help on a specific command

Available commands:
backtrace

delete

enable

help

list

pry

restart

source

undisplay

break

disable

eval

info

method

ps

save

start

up

catch

display

exit

irb

next

putl

set

step

var

condition

down

finish

jump

p

quit

show

thread

where

continue

edit

frame

kill

pp

reload

skip

trace
Program info
(rdb:4) help info
Generic command for showing things about the program being debugged.
-List of info subcommands:
-info args -- Argument variables of current stack frame
info breakpoints -- Status of user-settable breakpoints
info catch -- Exceptions that can be caught in the current stack frame
info display -- Expressions to display when program stops
info file -- Info about a particular file read in
info files -- File names and timestamps of files read in
info global_variables -- Global variables
info instance_variables -- Instance variables of the current stack frame
info line -- Line number and file name of current position in source file
info locals -- Local variables of the current stack frame
info program -- Execution status of the program
info stack -- Backtrace of the stack
info thread -- List info about thread NUM
info threads -- information of currently-known threads
info variables -- Local and instance variables of the current stack frame
Listing
(rdb:1) help list
l[ist]

list forward

l[ist] -

list backward

l[ist] =

list current line

l[ist] nn-mm

list given lines

NOTE - to turn on autolist, use 'set autolist' -> .rdebugrc
Listing: in debug
12

@user = User.find(params[:id])

13

debugger

=> 14
15
16

@microposts = @user.microposts.paginate(page: params[:page])
end
Listing: l 23,25
l 23,25
[23, 25] in */sample_app_rails_4/app/controllers/users_controller.rb
23

if @user.save

24

sign_in @user

25

flash[:success] = "Welcome to the Sample App!"
Breakpoints
(rdb:4) help break
b[reak] file:line [if expr]
b[reak] class(.|#)method [if expr]
set breakpoint to some position, (optionally) if expr == true
(rdb:4) help delete
del[ete][ nnn...]

delete some or all breakpoints
Set breakpoint
(rdb:4) b ApplicationHelper#full_title
Breakpoint 1 at ApplicationHelper::full_title
(rdb:4) b 18
Breakpoint 2 file */sample_app_rails_4/app/controllers/users_controller.rb, line 18
(rdb:4) info b
Num Enb What
1 y

at ApplicationHelper:full_title

2 y

at */sample_app_rails_4/app/controllers/users_controller.rb:18
Navigate
(rdb:4) help step
s[tep][+-]?[ nnn]

step (into methods) once or nnn times

'+' forces to move to another line.
'-' is the opposite of '+' and disables the force_stepping setting.
(rdb:4) help next
n[ext][+-]?[ nnn]

step over once or nnn times,

'+' forces to move to another line.
'-' is the opposite of '+' and disables the force_stepping setting.
(rdb:4) help up
up[count]

move to higher frame
Stop at breakpoint
(rdb:4) c
Breakpoint 1 at ApplicationHelper:full_title
[-1, 8] in */sample_app_rails_4/app/helpers/application_helper.rb
1

module ApplicationHelper

2
3
=> 4
5

# Returns the full title on a per-page basis.
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
Display
(rdb:4) help display
disp[lay] <expression>

add expression into display expression list

disp[lay]

display expression list

(rdb:4) help undisplay
undisp[lay][ nnn]
Cancel some expressions to be displayed when program stops.
Display configured
4
=> 5
6

def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?

(rdb:4) disp
2: controller_name = users
3: base_title =
Display changed
(rdb:4) n
*/sample_app_rails_4/app/helpers/application_helper.rb:6
if page_title.empty?

2: controller_name = users
3: base_title = Ruby on Rails Tutorial Sample App
[1, 10] in */sample_app_rails_4/app/helpers/application_helper.rb
5
=> 6
7

base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
Conditional breakpoint
(rdb:8) b ApplicationHelper#full_title if page_title=="Alexander"
Breakpoint 4 at ApplicationHelper::full_title
(rdb:8) c
Breakpoint 1 at ApplicationHelper:full_title
Variables
(rdb:8) help var
v[ar] cl[ass]

show class variables of self

v[ar] co[nst] <object>

show constants of object

v[ar] g[lobal]

show global variables

v[ar] i[nstance] <object>

show instance variables of object. You may pass object id's hex as well.

v[ar] l[ocal]

show local variables
Show variables
12

@user = User.find(params[:id])

13

debugger

=> 14
15

@microposts = @user.microposts.paginate(page: params[:page])
end

16
17

def new

(rdb:12) v i
@_action_has_layout = true
@_action_name = "show"
@_config = {}
@_env = {"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/users/1", "QUERY_STRING"=>"",...
@_headers = {"Content-Type"=>"text/html"}
@_lookup_context = #<ActionView::LookupContext:0x00000008e4b710 @details_key=nil, @details={:loc...
@_params = {"action"=>"show", "controller"=>"users", "id"=>"1"}
@_prefixes = ["users", "application"]
@_request = #<ActionDispatch::Request:0x00000008e4bad0 @env={"GATEWAY_INTERFACE"=>"CGI/1....
@_response = #<ActionDispatch::Response:0x00000008e4baa8 @mon_owner=nil, @mon_count=0, @mo...
@_response_body = nil
@_routes = nil
@_status = 200
@user = #<User id: 1, name: "Alexander", email: "asdf@asdf.com", created_at: "2013-11...
Remote debugger
Server
Debugger.wait_connection = true
Debugger.start_remote

Client
# rdebug --client -h 127.0.0.1
Connected.

*/sample_app_rails_4/app/controllers/users_controller.rb:14
@microposts = @user.microposts.paginate(page: params[:page])

[9, 18] in */sample_app_rails_4/app/controllers/users_controller.rb
9

end

10
11

def show

12

@user = User.find(params[:id])

13

debugger

=> 14

@microposts = @user.microposts.paginate(page: params[:page])
pry
REPL
debugger-pry
Call pry from debugger
pry-debugger
Debugger commands inside pry:
step, next, continue, breakpoints
jazz_hands
jazz_hands is an opinionated set of consolerelated gems and a bit of glue:
pry, awesome_print, hirb, pry-rails, pry-doc, pry-git,
pry-remote, pry-debugger, pry-stack_explorer, coolline,
coderay
pry – jazz_hands 1
pry – jazz_hands 2
pry – jazz_hands 3
pry – jazz_hands 4
Logging
ActiveSupport::Logger

is used for logging

Rails.root/log/[environment_name].log
Log levels
Rails.logger.level

| name

| level |

|----------+-------|
| :debug

|

0 |

| :info

|

1 |

| :warn

|

2 |

| :error

|

3 |

| :fatal

|

4 |

| :unknown |

5 |

development, testing:
production:

log_level = 0 (:debug)

log_level = 1

Messages with equal or higher level are sent to log
Write to log
logger.debug User.inspect
logger.info user.id
logger.fatal "Help!"
Tagging log messages
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged("USER") { logger.info "hello" }
=> [USER] hello
Tagged logging
def show
@user = User.find(params[:id])
logger.tagged("USER") { logger.info @user.email }

# tail -f log/development.log|grep [USER]
[USER] asdf@asdf.com
Global variables for tracing
__FILE__

- file name

__LINE__

- line number
Some useful CLI commands
tail -n 100
tail -f
grep, less
Querying logs
# cat log/development.log|grep GET|tail -n 2
Started GET "/assets/users.js?body=1" for 127.0.0.1 at 2013-11-21 23:32:01 +0200
Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2013-11-21 23:32:01 +0200

# cat log/development.log|grep GET|wc -l
574
config.log_formatter
Defines the formatter of the Rails logger.
Defaults to

ActiveSupport::Logger::SimpleFormatter

production defaults to

for all modes,

Logger::Formatter.

module ActiveSupport
class Logger < ::Logger

# Simple formatter which only displays the message.
class SimpleFormatter < ::Logger::Formatter
# This method is invoked when a log event occurs
def call(severity, timestamp, progname, msg)
"#{String === msg ? msg : msg.inspect}n"
end
end
config.log_level
Defaults to

:debug

for all modes, production defaults to

:info.
config.log_tags
See

ActionDispatch::Request

methods.

config.log_tags = [ :fullpath ]

[/users/1] Started GET "/users/1" for 127.0.0.1 at 2013-11-...
[/users/1]

ActiveRecord::SchemaMigration Load (0.1ms)

SELECT ...

[/assets/application.css?body=1] Started GET "/assets/application.css?body=1" for 127...
config.logger
Accepts a logger conforming to the interface of Log4r or the default Ruby Logger class.
Defaults to

ActiveSupport::Logger,

with auto flushing off in production mode.
Rails console
rails c
rails c --sandbox

irb
pry
rake routes
> all_routes = Rails.application.routes.routes
> require 'action_dispatch/routing/inspector'
> inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
All routes
> puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new)
Prefix Verb

URI Pattern

Controller#Action

following_user GET

/users/:id/following(.:format) users#following

followers_user GET

/users/:id/followers(.:format) users#followers

users GET

/users(.:format)

users#index

/users(.:format)

users#create

/users/new(.:format)

users#new

/users/:id/edit(.:format)

users#edit

/users/:id(.:format)

users#show

PATCH

/users/:id(.:format)

users#update

PUT

/users/:id(.:format)

users#update

POST
new_user GET
edit_user GET
user GET

DELETE /users/:id(.:format)
sessions POST
new_session GET

/sessions(.:format)

sessions#create

/sessions/new(.:format)

sessions#new

session DELETE /sessions/:id(.:format)
microposts POST

/microposts(.:format)

micropost DELETE /microposts/:id(.:format)
relationships POST

/relationships(.:format)

relationship DELETE /relationships/:id(.:format)
root GET
signup GET

users#destroy

sessions#destroy
microposts#create
microposts#destroy
relationships#create
relationships#destroy

/

static_pages#home

/signup(.:format)

users#new
Routes for controller
> puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, 'microposts')
Prefix Verb
microposts POST

URI Pattern

Controller#Action

/microposts(.:format)

microposts#create

micropost DELETE /microposts/:id(.:format) microposts#destroy
Filtering routes: GET
> puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, 'users').lines.grep(/GET/).join
following_user GET

/users/:id/following(.:format) users#following

followers_user GET

/users/:id/followers(.:format) users#followers

users GET
new_user GET
edit_user GET
user GET
signup GET

/users(.:format)

users#index

/users/new(.:format)

users#new

/users/:id/edit(.:format)

users#edit

/users/:id(.:format)

users#show

/signup(.:format)

users#new
Filtering routes: /relation/
> puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new).lines.grep(/relation/).join
relationships POST

/relationships(.:format)

relationship DELETE /relationships/:id(.:format)

relationships#create
relationships#destroy
Matching routes
> r = Rails.application.routes
> r.recognize_path "/users/47"
=> {:action=>"show", :controller=>"users", :id=>"47"}
> r.recognize_path "/users/87", :method => "PUT"
=> {:action=>"update", :controller=>"users", :id=>"87"}
> r.recognize_path "/users/47.json"
=> {:action=>"show", :controller=>"users", :id=>"47", :format=>"json"}
Named routes
> app.users_path
=> "/users"
> app.users_path(:json)
=> "/users.json"
> app.user_path(1)
=> "/users/1"
> app.user_path(1, :xml)
=> "/users/1.xml"
> app.user_path(1, :count => 4)
=> "/users/1?count=4"
Making requests
> app
=> #<ActionDispatch::Integration::Session:...>

> app.reset!
Get requests
> app.get '/users/1/edit'

Started GET "/users/1/edit" for 127.0.0.1 at 2013-11-26 23:24:18 +0200
Processing by UsersController#edit as HTML
Parameters: {"id"=>"1"}
Redirected to http://localhost:3000/signin
Filter chain halted as :signed_in_user rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.4ms)

> app.response.body
=> "<html><body>You are being <a href="http://localhost:3000/signin">redirected</a>.</body></html>"

> app.get_via_redirect '/users/1/edit'

Started GET "/users/1/edit" for 127.0.0.1 at 2013-11-26 23:26:44 +0200
Redirected to http://localhost:3000/signin
...
Started GET "/signin" for 127.0.0.1 at 2013-11-26 23:26:44 +0200
Session cookies
> app.cookies
=> #<Rack::Test::CookieJar...

> app.cookies.to_hash
=> {"_sample_app_session"=>"RC9j...

app.cookies - received/sent cookies
Post requests: signin
> app.response.body.lines.grep /csrf-token/
=> ["<meta content="n+9uCcG2JJmgwhnNcp4s9jTwOU55RAPOdtAHWstcpKQ=" name="csrf-token" />n"]

> app.post '/sessions', :authenticity_token => 'n+9uCcG2JJmgwhnNcp4s9jTwOU55RAPOdtAHWstcpKQ=',
'session[email]' => 'asdf@asdf.com', 'session[password]' => '123456'

Started POST "/sessions" for 127.0.0.1 at 2013-11-26 23:33:01 +0200
Processing by SessionsController#create as HTML
Parameters: {"authenticity_token"=>"n+9uCcG2JJmgwhnNcp4s9jTwOU55RAPOdtAHWstcpKQ=", "session"=>{"email"
=>"asdf@asdf.com", "password"=>"[FILTERED]"}}
Redirected to http://localhost:3000/users/1/edit
Completed 302 Found in 281ms (ActiveRecord: 7.2ms)

app.post_via_redirect
Access to restricted resource
> app.get '/users/1/edit'

Started GET "/users/1/edit" for 127.0.0.1 at 2013-11-26 23:38:47 +0200
Processing by UsersController#edit as HTML
Completed 200 OK in 41ms (Views: 35.7ms | ActiveRecord: 0.8ms)
Call helper
> helper
=> #<ActionView::Base:... >
# ApplicationHelper#full_title
> helper.full_title "Sign Up"
=> "Ruby on Rails Tutorial Sample App | Sign Up"
Call helper with cookie
> def cookies; @cookies ||= HashWithIndifferentAccess.new(app.cookies.to_hash); end

> helper.current_user
=> #<User id: 1, name: ....
ActiveRecord logging
> ActiveRecord::Base.logger = Logger.new(STDOUT)
> ActiveRecord::Base.clear_active_connections!
> # reload!
> User.find 1
D, [2013-12-30T21:55:17.775769 #24810] DEBUG -- :
WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
=> #<User id: 1, name: "hello",....

User Load (0.2ms)

SELECT "users".* FROM "users"
ActiveRecord hide logging
> ActiveRecord::Base.logger = Logger.new(nil)
> ActiveRecord::Base.clear_active_connections!
> # reload!
> User.find 1
=> #<User id: 1, name: "hello",....
Raw SQL requests
> ActiveRecord::Base.connection.select_all("select * from users")
=> #<ActiveRecord::Result:...
> puts _
{"id"=>1, "name"=>"hello", "email"=>"hello@hello.com", "created_at"=>"2013-....
.irbrc
Save your helper methods
● routes
● sql logging
● etc
CLI tools
Making HTTP requests with curl
●
●
●
●
●
●

-s silent
-v verbose
-c save cookie
-b use cookie
-data POST data
-data-urlencode URL-encode POST data
Access restricted area
curl -s -v http://localhost:3000/users/1/edit > /dev/null

> GET /users/1/edit HTTP/1.1
< HTTP/1.1 302 Found
< Location: http://localhost:3000/signin
Visit /signin, get token
curl -s -c hello_cookies http://localhost:3000/signin > /dev/null |grep csrf-token

<meta content="/t/IoUQxKVEL+KR2/HsnxTKmnALUA99jIr/LvjlgPKs=" name="csrf-token" />
Sign in
curl -s -v --data "session[email]=asdf@asdf.com;session[password]=123456" 
--data-urlencode "authenticity_token=/t/IoUQxKVEL+KR2/HsnxTKmnALUA99jIr/LvjlgPKs=" 
-b hello_cookies -c cookies 
http://localhost:3000/sessions > /dev/null

> POST /sessions HTTP/1.1
< HTTP/1.1 302 Found
< Location: http://localhost:3000/users/1
Successful access to restricted area
curl -s -v http://localhost:3000/users/1/edit -b cookies > /dev/null
> GET /users/1/edit HTTP/1.1
< HTTP/1.1 200 OK
Browser tools
●
●
●
●

console
render helpers
debug info
etc
rack-webconsole
>> User.find 1
=> #<User id: 1, name: "Alexander", email: "asdf@asdf.com", created_at: "2013-11-17 16:19:07",
updated_at: "2013-11-27 21:52:06", password_digest:
"$2a$10$MEICr2zekeBhh9HYCMLmXut3ckOsiL0TkksFWVX4asFf...", remember_token:
"cda4da34a5ee4238ddb78f20d4ec7e52b59fab4e", admin: nil>
>> helper
=> Error: undefined local variable or method `helper' for #<Rack::Webconsole::Sandbox:0x000000089cf600>
>> app
=> Error: undefined local variable or method `app' for #<Rack::Webconsole::Sandbox:0x000000089cf600>
>> Rails.root
=> #<Pathname:*/sample_app_rails_4>
>> self
=> #<Rack::Webconsole::Sandbox:0x000000089cf600 @locals={:u=>#<User id: 1, name: "Alexander"
rack-webconsole

`

- activate
Rails Panel
rails-footnotes: Assigns
rails-footnotes: DB
rails-footnotes: disable
?footnotes=false
xray-rails
Ctrl+Shift+X
better_errors 1
better_errors 2
exception_notifier
Provides a set of notifiers for sending
notifications when errors occur in a Rack/Rails
application
letter_opener
Preview email in the browser instead of
sending it
exception_notifier + letter_opener
Chrome: Form Editor
Chrome: JunkFill
Chrome: Sight
API calls, sight
hurl.it: params
hurl.it: response
POSTMAN
Chrome: REST console
Chrome: Advanced Rest Client
ВСЁ

More Related Content

What's hot

Common mistakes made with Functional Java
Common mistakes made with Functional JavaCommon mistakes made with Functional Java
Common mistakes made with Functional Java
Brian Vermeer
 
Common mistakes functional java devoxx
Common mistakes functional java devoxxCommon mistakes functional java devoxx
Common mistakes functional java devoxx
Brian Vermeer
 
Codeigniter4の比較と検証
Codeigniter4の比較と検証Codeigniter4の比較と検証
Codeigniter4の比較と検証
ME iBotch
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
Eueung Mulyana
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
Workhorse Computing
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6
Workhorse Computing
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Puppet
 
The Story About The Migration
 The Story About The Migration The Story About The Migration
The Story About The Migration
EDB
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
Alessandro Cucci
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
Workhorse Computing
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
Workhorse Computing
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
Workhorse Computing
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
Workhorse Computing
 
2005_Structures and functions of Makefile
2005_Structures and functions of Makefile2005_Structures and functions of Makefile
2005_Structures and functions of MakefileNakCheon Jung
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjug
Brian Vermeer
 
Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018
Brian Vermeer
 
Perl one-liners
Perl one-linersPerl one-liners
Perl one-liners
daoswald
 

What's hot (20)

Common mistakes made with Functional Java
Common mistakes made with Functional JavaCommon mistakes made with Functional Java
Common mistakes made with Functional Java
 
Common mistakes functional java devoxx
Common mistakes functional java devoxxCommon mistakes functional java devoxx
Common mistakes functional java devoxx
 
Codeigniter4の比較と検証
Codeigniter4の比較と検証Codeigniter4の比較と検証
Codeigniter4の比較と検証
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
 
The Story About The Migration
 The Story About The Migration The Story About The Migration
The Story About The Migration
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
2005_Structures and functions of Makefile
2005_Structures and functions of Makefile2005_Structures and functions of Makefile
2005_Structures and functions of Makefile
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjug
 
Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018
 
Perl one-liners
Perl one-linersPerl one-liners
Perl one-liners
 

Similar to Debugging on Rails. Mykhaylo Sorochan

Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
sickill
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbJuan Maiz
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron Patterson
ManageIQ
 
A Z Introduction To Ruby On Rails
A Z Introduction To Ruby On RailsA Z Introduction To Ruby On Rails
A Z Introduction To Ruby On Railsrailsconf
 
A-Z Intro To Rails
A-Z Intro To RailsA-Z Intro To Rails
A-Z Intro To Rails
Robert Dempsey
 
Rails MVC by Sergiy Koshovyi
Rails MVC by Sergiy KoshovyiRails MVC by Sergiy Koshovyi
Rails MVC by Sergiy Koshovyi
Pivorak MeetUp
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
Daniel Cukier
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
Laravel tips-2019-04
Laravel tips-2019-04Laravel tips-2019-04
Laravel tips-2019-04
Fernando Andrés Pérez Alarcón
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
Pedro Cunha
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
Plataformatec
 
Otimizando Aplicações em Rails
Otimizando Aplicações em RailsOtimizando Aplicações em Rails
Otimizando Aplicações em Rails
Juan Maiz
 
Rails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not KnowRails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not Know
Chris Oliver
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amfrailsconf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
Tony Hillerson
 
Ruby meetup-dry
Ruby meetup-dryRuby meetup-dry
Ruby meetup-dry
Nikita Shilnikov
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in Ruby
Nikhil Mungel
 

Similar to Debugging on Rails. Mykhaylo Sorochan (20)

Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Background Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRbBackground Jobs - Com BackgrounDRb
Background Jobs - Com BackgrounDRb
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron Patterson
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
A Z Introduction To Ruby On Rails
A Z Introduction To Ruby On RailsA Z Introduction To Ruby On Rails
A Z Introduction To Ruby On Rails
 
A-Z Intro To Rails
A-Z Intro To RailsA-Z Intro To Rails
A-Z Intro To Rails
 
Rails MVC by Sergiy Koshovyi
Rails MVC by Sergiy KoshovyiRails MVC by Sergiy Koshovyi
Rails MVC by Sergiy Koshovyi
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Laravel tips-2019-04
Laravel tips-2019-04Laravel tips-2019-04
Laravel tips-2019-04
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
Otimizando Aplicações em Rails
Otimizando Aplicações em RailsOtimizando Aplicações em Rails
Otimizando Aplicações em Rails
 
Rails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not KnowRails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not Know
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Ruby meetup-dry
Ruby meetup-dryRuby meetup-dry
Ruby meetup-dry
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in Ruby
 

More from Sphere Consulting Inc

Anton Vasiljev: Continuations in Ruby.
Anton Vasiljev: Continuations in Ruby.Anton Vasiljev: Continuations in Ruby.
Anton Vasiljev: Continuations in Ruby.
Sphere Consulting Inc
 
Anton Shemerey: Refactoring and SOLID principles in Ruby.
Anton Shemerey: Refactoring and SOLID principles in Ruby.Anton Shemerey: Refactoring and SOLID principles in Ruby.
Anton Shemerey: Refactoring and SOLID principles in Ruby.
Sphere Consulting Inc
 
Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.
Sphere Consulting Inc
 
Valeriy Prokopchuk: Validators in Migrations.
Valeriy Prokopchuk: Validators in Migrations.Valeriy Prokopchuk: Validators in Migrations.
Valeriy Prokopchuk: Validators in Migrations.
Sphere Consulting Inc
 
Roman Kuznietsov: Zeromq: sockets on steroids.Zero mq
Roman Kuznietsov: Zeromq: sockets on steroids.Zero mqRoman Kuznietsov: Zeromq: sockets on steroids.Zero mq
Roman Kuznietsov: Zeromq: sockets on steroids.Zero mq
Sphere Consulting Inc
 
OpenSource Project. Where to Start? Dmitriy Zaporozhets
OpenSource Project. Where to Start? Dmitriy ZaporozhetsOpenSource Project. Where to Start? Dmitriy Zaporozhets
OpenSource Project. Where to Start? Dmitriy Zaporozhets
Sphere Consulting Inc
 
FormObject For Building Complex Forms. Dmytro Pilugin
FormObject For Building Complex Forms. Dmytro PiluginFormObject For Building Complex Forms. Dmytro Pilugin
FormObject For Building Complex Forms. Dmytro Pilugin
Sphere Consulting Inc
 
Asynchronous Applications in Ruby. Roman Gorel
Asynchronous Applications in Ruby. Roman GorelAsynchronous Applications in Ruby. Roman Gorel
Asynchronous Applications in Ruby. Roman Gorel
Sphere Consulting Inc
 

More from Sphere Consulting Inc (8)

Anton Vasiljev: Continuations in Ruby.
Anton Vasiljev: Continuations in Ruby.Anton Vasiljev: Continuations in Ruby.
Anton Vasiljev: Continuations in Ruby.
 
Anton Shemerey: Refactoring and SOLID principles in Ruby.
Anton Shemerey: Refactoring and SOLID principles in Ruby.Anton Shemerey: Refactoring and SOLID principles in Ruby.
Anton Shemerey: Refactoring and SOLID principles in Ruby.
 
Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.
 
Valeriy Prokopchuk: Validators in Migrations.
Valeriy Prokopchuk: Validators in Migrations.Valeriy Prokopchuk: Validators in Migrations.
Valeriy Prokopchuk: Validators in Migrations.
 
Roman Kuznietsov: Zeromq: sockets on steroids.Zero mq
Roman Kuznietsov: Zeromq: sockets on steroids.Zero mqRoman Kuznietsov: Zeromq: sockets on steroids.Zero mq
Roman Kuznietsov: Zeromq: sockets on steroids.Zero mq
 
OpenSource Project. Where to Start? Dmitriy Zaporozhets
OpenSource Project. Where to Start? Dmitriy ZaporozhetsOpenSource Project. Where to Start? Dmitriy Zaporozhets
OpenSource Project. Where to Start? Dmitriy Zaporozhets
 
FormObject For Building Complex Forms. Dmytro Pilugin
FormObject For Building Complex Forms. Dmytro PiluginFormObject For Building Complex Forms. Dmytro Pilugin
FormObject For Building Complex Forms. Dmytro Pilugin
 
Asynchronous Applications in Ruby. Roman Gorel
Asynchronous Applications in Ruby. Roman GorelAsynchronous Applications in Ruby. Roman Gorel
Asynchronous Applications in Ruby. Roman Gorel
 

Recently uploaded

FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
Globus
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
Jen Stirrup
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
UiPathCommunity
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 

Debugging on Rails. Mykhaylo Sorochan

  • 1. kiev.rb #2 kiev #2 .rb Debugging on Rails Mykhaylo Sorochan
  • 3. Debugged application Sample app for the Ruby on Rails Tutorial (Rails 4) https://github.com/railstutorial/sample_app_rails_4
  • 4. debugger gem 'debugger' debugger - call debugger config - .rdebugrc
  • 5. Debug location UserController#show def show @user = User.find(params[:id]) debugger @microposts = @user.microposts.paginate(page: params[:page]) end
  • 6. Debugger commands (rdb:9) help ruby-debug help v1.6.2 Type 'help <command-name>' for help on a specific command Available commands: backtrace delete enable help list pry restart source undisplay break disable eval info method ps save start up catch display exit irb next putl set step var condition down finish jump p quit show thread where continue edit frame kill pp reload skip trace
  • 7. Program info (rdb:4) help info Generic command for showing things about the program being debugged. -List of info subcommands: -info args -- Argument variables of current stack frame info breakpoints -- Status of user-settable breakpoints info catch -- Exceptions that can be caught in the current stack frame info display -- Expressions to display when program stops info file -- Info about a particular file read in info files -- File names and timestamps of files read in info global_variables -- Global variables info instance_variables -- Instance variables of the current stack frame info line -- Line number and file name of current position in source file info locals -- Local variables of the current stack frame info program -- Execution status of the program info stack -- Backtrace of the stack info thread -- List info about thread NUM info threads -- information of currently-known threads info variables -- Local and instance variables of the current stack frame
  • 8. Listing (rdb:1) help list l[ist] list forward l[ist] - list backward l[ist] = list current line l[ist] nn-mm list given lines NOTE - to turn on autolist, use 'set autolist' -> .rdebugrc
  • 9. Listing: in debug 12 @user = User.find(params[:id]) 13 debugger => 14 15 16 @microposts = @user.microposts.paginate(page: params[:page]) end
  • 10. Listing: l 23,25 l 23,25 [23, 25] in */sample_app_rails_4/app/controllers/users_controller.rb 23 if @user.save 24 sign_in @user 25 flash[:success] = "Welcome to the Sample App!"
  • 11. Breakpoints (rdb:4) help break b[reak] file:line [if expr] b[reak] class(.|#)method [if expr] set breakpoint to some position, (optionally) if expr == true (rdb:4) help delete del[ete][ nnn...] delete some or all breakpoints
  • 12. Set breakpoint (rdb:4) b ApplicationHelper#full_title Breakpoint 1 at ApplicationHelper::full_title (rdb:4) b 18 Breakpoint 2 file */sample_app_rails_4/app/controllers/users_controller.rb, line 18 (rdb:4) info b Num Enb What 1 y at ApplicationHelper:full_title 2 y at */sample_app_rails_4/app/controllers/users_controller.rb:18
  • 13. Navigate (rdb:4) help step s[tep][+-]?[ nnn] step (into methods) once or nnn times '+' forces to move to another line. '-' is the opposite of '+' and disables the force_stepping setting. (rdb:4) help next n[ext][+-]?[ nnn] step over once or nnn times, '+' forces to move to another line. '-' is the opposite of '+' and disables the force_stepping setting. (rdb:4) help up up[count] move to higher frame
  • 14. Stop at breakpoint (rdb:4) c Breakpoint 1 at ApplicationHelper:full_title [-1, 8] in */sample_app_rails_4/app/helpers/application_helper.rb 1 module ApplicationHelper 2 3 => 4 5 # Returns the full title on a per-page basis. def full_title(page_title) base_title = "Ruby on Rails Tutorial Sample App"
  • 15. Display (rdb:4) help display disp[lay] <expression> add expression into display expression list disp[lay] display expression list (rdb:4) help undisplay undisp[lay][ nnn] Cancel some expressions to be displayed when program stops.
  • 16. Display configured 4 => 5 6 def full_title(page_title) base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? (rdb:4) disp 2: controller_name = users 3: base_title =
  • 17. Display changed (rdb:4) n */sample_app_rails_4/app/helpers/application_helper.rb:6 if page_title.empty? 2: controller_name = users 3: base_title = Ruby on Rails Tutorial Sample App [1, 10] in */sample_app_rails_4/app/helpers/application_helper.rb 5 => 6 7 base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? base_title
  • 18. Conditional breakpoint (rdb:8) b ApplicationHelper#full_title if page_title=="Alexander" Breakpoint 4 at ApplicationHelper::full_title (rdb:8) c Breakpoint 1 at ApplicationHelper:full_title
  • 19. Variables (rdb:8) help var v[ar] cl[ass] show class variables of self v[ar] co[nst] <object> show constants of object v[ar] g[lobal] show global variables v[ar] i[nstance] <object> show instance variables of object. You may pass object id's hex as well. v[ar] l[ocal] show local variables
  • 20. Show variables 12 @user = User.find(params[:id]) 13 debugger => 14 15 @microposts = @user.microposts.paginate(page: params[:page]) end 16 17 def new (rdb:12) v i @_action_has_layout = true @_action_name = "show" @_config = {} @_env = {"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/users/1", "QUERY_STRING"=>"",... @_headers = {"Content-Type"=>"text/html"} @_lookup_context = #<ActionView::LookupContext:0x00000008e4b710 @details_key=nil, @details={:loc... @_params = {"action"=>"show", "controller"=>"users", "id"=>"1"} @_prefixes = ["users", "application"] @_request = #<ActionDispatch::Request:0x00000008e4bad0 @env={"GATEWAY_INTERFACE"=>"CGI/1.... @_response = #<ActionDispatch::Response:0x00000008e4baa8 @mon_owner=nil, @mon_count=0, @mo... @_response_body = nil @_routes = nil @_status = 200 @user = #<User id: 1, name: "Alexander", email: "asdf@asdf.com", created_at: "2013-11...
  • 21. Remote debugger Server Debugger.wait_connection = true Debugger.start_remote Client # rdebug --client -h 127.0.0.1 Connected. */sample_app_rails_4/app/controllers/users_controller.rb:14 @microposts = @user.microposts.paginate(page: params[:page]) [9, 18] in */sample_app_rails_4/app/controllers/users_controller.rb 9 end 10 11 def show 12 @user = User.find(params[:id]) 13 debugger => 14 @microposts = @user.microposts.paginate(page: params[:page])
  • 24. pry-debugger Debugger commands inside pry: step, next, continue, breakpoints
  • 25. jazz_hands jazz_hands is an opinionated set of consolerelated gems and a bit of glue: pry, awesome_print, hirb, pry-rails, pry-doc, pry-git, pry-remote, pry-debugger, pry-stack_explorer, coolline, coderay
  • 30. Logging ActiveSupport::Logger is used for logging Rails.root/log/[environment_name].log
  • 31. Log levels Rails.logger.level | name | level | |----------+-------| | :debug | 0 | | :info | 1 | | :warn | 2 | | :error | 3 | | :fatal | 4 | | :unknown | 5 | development, testing: production: log_level = 0 (:debug) log_level = 1 Messages with equal or higher level are sent to log
  • 32. Write to log logger.debug User.inspect logger.info user.id logger.fatal "Help!"
  • 33. Tagging log messages logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) logger.tagged("USER") { logger.info "hello" } => [USER] hello
  • 34. Tagged logging def show @user = User.find(params[:id]) logger.tagged("USER") { logger.info @user.email } # tail -f log/development.log|grep [USER] [USER] asdf@asdf.com
  • 35. Global variables for tracing __FILE__ - file name __LINE__ - line number
  • 36. Some useful CLI commands tail -n 100 tail -f grep, less
  • 37. Querying logs # cat log/development.log|grep GET|tail -n 2 Started GET "/assets/users.js?body=1" for 127.0.0.1 at 2013-11-21 23:32:01 +0200 Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2013-11-21 23:32:01 +0200 # cat log/development.log|grep GET|wc -l 574
  • 38. config.log_formatter Defines the formatter of the Rails logger. Defaults to ActiveSupport::Logger::SimpleFormatter production defaults to for all modes, Logger::Formatter. module ActiveSupport class Logger < ::Logger # Simple formatter which only displays the message. class SimpleFormatter < ::Logger::Formatter # This method is invoked when a log event occurs def call(severity, timestamp, progname, msg) "#{String === msg ? msg : msg.inspect}n" end end
  • 39. config.log_level Defaults to :debug for all modes, production defaults to :info.
  • 40. config.log_tags See ActionDispatch::Request methods. config.log_tags = [ :fullpath ] [/users/1] Started GET "/users/1" for 127.0.0.1 at 2013-11-... [/users/1] ActiveRecord::SchemaMigration Load (0.1ms) SELECT ... [/assets/application.css?body=1] Started GET "/assets/application.css?body=1" for 127...
  • 41. config.logger Accepts a logger conforming to the interface of Log4r or the default Ruby Logger class. Defaults to ActiveSupport::Logger, with auto flushing off in production mode.
  • 42. Rails console rails c rails c --sandbox irb pry
  • 43. rake routes > all_routes = Rails.application.routes.routes > require 'action_dispatch/routing/inspector' > inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
  • 44. All routes > puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new) Prefix Verb URI Pattern Controller#Action following_user GET /users/:id/following(.:format) users#following followers_user GET /users/:id/followers(.:format) users#followers users GET /users(.:format) users#index /users(.:format) users#create /users/new(.:format) users#new /users/:id/edit(.:format) users#edit /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update POST new_user GET edit_user GET user GET DELETE /users/:id(.:format) sessions POST new_session GET /sessions(.:format) sessions#create /sessions/new(.:format) sessions#new session DELETE /sessions/:id(.:format) microposts POST /microposts(.:format) micropost DELETE /microposts/:id(.:format) relationships POST /relationships(.:format) relationship DELETE /relationships/:id(.:format) root GET signup GET users#destroy sessions#destroy microposts#create microposts#destroy relationships#create relationships#destroy / static_pages#home /signup(.:format) users#new
  • 45. Routes for controller > puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, 'microposts') Prefix Verb microposts POST URI Pattern Controller#Action /microposts(.:format) microposts#create micropost DELETE /microposts/:id(.:format) microposts#destroy
  • 46. Filtering routes: GET > puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, 'users').lines.grep(/GET/).join following_user GET /users/:id/following(.:format) users#following followers_user GET /users/:id/followers(.:format) users#followers users GET new_user GET edit_user GET user GET signup GET /users(.:format) users#index /users/new(.:format) users#new /users/:id/edit(.:format) users#edit /users/:id(.:format) users#show /signup(.:format) users#new
  • 47. Filtering routes: /relation/ > puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new).lines.grep(/relation/).join relationships POST /relationships(.:format) relationship DELETE /relationships/:id(.:format) relationships#create relationships#destroy
  • 48. Matching routes > r = Rails.application.routes > r.recognize_path "/users/47" => {:action=>"show", :controller=>"users", :id=>"47"} > r.recognize_path "/users/87", :method => "PUT" => {:action=>"update", :controller=>"users", :id=>"87"} > r.recognize_path "/users/47.json" => {:action=>"show", :controller=>"users", :id=>"47", :format=>"json"}
  • 49. Named routes > app.users_path => "/users" > app.users_path(:json) => "/users.json" > app.user_path(1) => "/users/1" > app.user_path(1, :xml) => "/users/1.xml" > app.user_path(1, :count => 4) => "/users/1?count=4"
  • 50. Making requests > app => #<ActionDispatch::Integration::Session:...> > app.reset!
  • 51. Get requests > app.get '/users/1/edit' Started GET "/users/1/edit" for 127.0.0.1 at 2013-11-26 23:24:18 +0200 Processing by UsersController#edit as HTML Parameters: {"id"=>"1"} Redirected to http://localhost:3000/signin Filter chain halted as :signed_in_user rendered or redirected Completed 302 Found in 3ms (ActiveRecord: 0.4ms) > app.response.body => "<html><body>You are being <a href="http://localhost:3000/signin">redirected</a>.</body></html>" > app.get_via_redirect '/users/1/edit' Started GET "/users/1/edit" for 127.0.0.1 at 2013-11-26 23:26:44 +0200 Redirected to http://localhost:3000/signin ... Started GET "/signin" for 127.0.0.1 at 2013-11-26 23:26:44 +0200
  • 52. Session cookies > app.cookies => #<Rack::Test::CookieJar... > app.cookies.to_hash => {"_sample_app_session"=>"RC9j... app.cookies - received/sent cookies
  • 53. Post requests: signin > app.response.body.lines.grep /csrf-token/ => ["<meta content="n+9uCcG2JJmgwhnNcp4s9jTwOU55RAPOdtAHWstcpKQ=" name="csrf-token" />n"] > app.post '/sessions', :authenticity_token => 'n+9uCcG2JJmgwhnNcp4s9jTwOU55RAPOdtAHWstcpKQ=', 'session[email]' => 'asdf@asdf.com', 'session[password]' => '123456' Started POST "/sessions" for 127.0.0.1 at 2013-11-26 23:33:01 +0200 Processing by SessionsController#create as HTML Parameters: {"authenticity_token"=>"n+9uCcG2JJmgwhnNcp4s9jTwOU55RAPOdtAHWstcpKQ=", "session"=>{"email" =>"asdf@asdf.com", "password"=>"[FILTERED]"}} Redirected to http://localhost:3000/users/1/edit Completed 302 Found in 281ms (ActiveRecord: 7.2ms) app.post_via_redirect
  • 54. Access to restricted resource > app.get '/users/1/edit' Started GET "/users/1/edit" for 127.0.0.1 at 2013-11-26 23:38:47 +0200 Processing by UsersController#edit as HTML Completed 200 OK in 41ms (Views: 35.7ms | ActiveRecord: 0.8ms)
  • 55. Call helper > helper => #<ActionView::Base:... > # ApplicationHelper#full_title > helper.full_title "Sign Up" => "Ruby on Rails Tutorial Sample App | Sign Up"
  • 56. Call helper with cookie > def cookies; @cookies ||= HashWithIndifferentAccess.new(app.cookies.to_hash); end > helper.current_user => #<User id: 1, name: ....
  • 57. ActiveRecord logging > ActiveRecord::Base.logger = Logger.new(STDOUT) > ActiveRecord::Base.clear_active_connections! > # reload! > User.find 1 D, [2013-12-30T21:55:17.775769 #24810] DEBUG -- : WHERE "users"."id" = ? LIMIT 1 [["id", 1]] => #<User id: 1, name: "hello",.... User Load (0.2ms) SELECT "users".* FROM "users"
  • 58. ActiveRecord hide logging > ActiveRecord::Base.logger = Logger.new(nil) > ActiveRecord::Base.clear_active_connections! > # reload! > User.find 1 => #<User id: 1, name: "hello",....
  • 59. Raw SQL requests > ActiveRecord::Base.connection.select_all("select * from users") => #<ActiveRecord::Result:... > puts _ {"id"=>1, "name"=>"hello", "email"=>"hello@hello.com", "created_at"=>"2013-....
  • 60. .irbrc Save your helper methods ● routes ● sql logging ● etc
  • 61. CLI tools Making HTTP requests with curl ● ● ● ● ● ● -s silent -v verbose -c save cookie -b use cookie -data POST data -data-urlencode URL-encode POST data
  • 62. Access restricted area curl -s -v http://localhost:3000/users/1/edit > /dev/null > GET /users/1/edit HTTP/1.1 < HTTP/1.1 302 Found < Location: http://localhost:3000/signin
  • 63. Visit /signin, get token curl -s -c hello_cookies http://localhost:3000/signin > /dev/null |grep csrf-token <meta content="/t/IoUQxKVEL+KR2/HsnxTKmnALUA99jIr/LvjlgPKs=" name="csrf-token" />
  • 64. Sign in curl -s -v --data "session[email]=asdf@asdf.com;session[password]=123456" --data-urlencode "authenticity_token=/t/IoUQxKVEL+KR2/HsnxTKmnALUA99jIr/LvjlgPKs=" -b hello_cookies -c cookies http://localhost:3000/sessions > /dev/null > POST /sessions HTTP/1.1 < HTTP/1.1 302 Found < Location: http://localhost:3000/users/1
  • 65. Successful access to restricted area curl -s -v http://localhost:3000/users/1/edit -b cookies > /dev/null > GET /users/1/edit HTTP/1.1 < HTTP/1.1 200 OK
  • 67. rack-webconsole >> User.find 1 => #<User id: 1, name: "Alexander", email: "asdf@asdf.com", created_at: "2013-11-17 16:19:07", updated_at: "2013-11-27 21:52:06", password_digest: "$2a$10$MEICr2zekeBhh9HYCMLmXut3ckOsiL0TkksFWVX4asFf...", remember_token: "cda4da34a5ee4238ddb78f20d4ec7e52b59fab4e", admin: nil> >> helper => Error: undefined local variable or method `helper' for #<Rack::Webconsole::Sandbox:0x000000089cf600> >> app => Error: undefined local variable or method `app' for #<Rack::Webconsole::Sandbox:0x000000089cf600> >> Rails.root => #<Pathname:*/sample_app_rails_4> >> self => #<Rack::Webconsole::Sandbox:0x000000089cf600 @locals={:u=>#<User id: 1, name: "Alexander"
  • 76. exception_notifier Provides a set of notifiers for sending notifications when errors occur in a Rack/Rails application
  • 77. letter_opener Preview email in the browser instead of sending it