+ All Categories
Home > Technology > Code diving in Ruby and Rails

Code diving in Ruby and Rails

Date post: 10-May-2015
Category:
Upload: lrdesign
View: 937 times
Download: 2 times
Share this document with a friend
Description:
Finding your way through foreign spaghetti code can be challenging. Learn to use Ruby's introspection tools to fearlessly code dive like a pro.
Popular Tags:
106
Code Diving in Ruby Evan Dorn Founder, Logical Reality Design http://lrdesign.com [email protected] @idahoev Friday, August 9, 13
Transcript
Page 1: Code diving in Ruby and Rails

Code Diving in Ruby

Evan DornFounder, Logical Reality Design

http://[email protected]

@idahoev

Friday, August 9, 13

Page 2: Code diving in Ruby and Rails

SO YOU’RE CODING ALONG WHEN...

Friday, August 9, 13

Page 3: Code diving in Ruby and Rails

1) InvoicesController as an admin GET index should paginate all unpaid invoices as @unpaid_invoices Failure/Error: get :index NoMethodError: undefined method `unpayed' for #<Class:0x007fd8cfe9ee18> # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/dynamic_matchers.rb:55:in `method_missing' # ./app/controllers/invoices_controller.rb:7:in `index' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/implicit_render.rb:4:in `send_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/base.rb:167:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/rendering.rb:10:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/callbacks.rb:18:in `block in process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:447:in `_run__3859364058582123788__process_action__4176185741589430016__callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:405:in `__run_callback' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:81:in `run_callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/callbacks.rb:17:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/rescue.rb:29:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'

Friday, August 9, 13

Page 4: Code diving in Ruby and Rails

AND YOU’RE LIKE

Friday, August 9, 13

Page 5: Code diving in Ruby and Rails

BUT THEN YOU NOTICE THIS...

Friday, August 9, 13

Page 6: Code diving in Ruby and Rails

1) InvoicesController as an admin GET index should paginate all unpaid invoices as @unpaid_invoices Failure/Error: get :index NoMethodError: undefined method `unpayed' for #<Class:0x007fd8cfe9ee18> # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/dynamic_matchers.rb:55:in `method_missing' # ./app/controllers/invoices_controller.rb:7:in `index' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/implicit_render.rb:4:in `send_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/base.rb:167:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/rendering.rb:10:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/callbacks.rb:18:in `block in process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:447:in `_run__3859364058582123788__process_action__4176185741589430016__callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:405:in `__run_callback' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:81:in `run_callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/callbacks.rb:17:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/rescue.rb:29:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'

Friday, August 9, 13

Page 7: Code diving in Ruby and Rails

1) InvoicesController as an admin GET index should paginate all unpaid invoices as @unpaid_invoices Failure/Error: get :index NoMethodError: undefined method `unpayed' for #<Class:0x007fd8cfe9ee18> # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/dynamic_matchers.rb:55:in `method_missing' # ./app/controllers/invoices_controller.rb:7:in `index' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/implicit_render.rb:4:in `send_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/base.rb:167:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/rendering.rb:10:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/callbacks.rb:18:in `block in process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:447:in `_run__3859364058582123788__process_action__4176185741589430016__callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:405:in `__run_callback' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:81:in `run_callbacks' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/abstract_controller/callbacks.rb:17:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/rescue.rb:29:in `process_action' # /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/actionpack-3.2.12/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'

Friday, August 9, 13

Page 8: Code diving in Ruby and Rails

BUT WHAT ABOUT WHEN...

Friday, August 9, 13

Page 9: Code diving in Ruby and Rails

/Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/core_ext/hash/keys.rb:25:in `symbolize_keys': You blew it, dumbass (RuntimeError) from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:45:in `resolve_hash_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:41:in `resolve_string_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:25:in `spec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:130:in `establish_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:82:in `block (2 levels) in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `instance_eval' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `execute_hook' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:26:in `block in on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:74:in `block in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `instance_exec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `run' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:55:in `block in run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/application.rb:136:in `initialize!' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/railtie/configurable.rb:30:in `method_missing' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/config/environment.rb:5:in `<top (required)>' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `require' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `<top

Friday, August 9, 13

Page 10: Code diving in Ruby and Rails

/Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/core_ext/hash/keys.rb:25:in `symbolize_keys': You blew it, dumbass (RuntimeError) from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:45:in `resolve_hash_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:41:in `resolve_string_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:25:in `spec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:130:in `establish_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:82:in `block (2 levels) in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `instance_eval' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `execute_hook' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:26:in `block in on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:74:in `block in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `instance_exec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `run' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:55:in `block in run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/application.rb:136:in `initialize!' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/railtie/configurable.rb:30:in `method_missing' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/config/environment.rb:5:in `<top (required)>' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `require' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `<top

Friday, August 9, 13

Page 11: Code diving in Ruby and Rails

/Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/core_ext/hash/keys.rb:25:in `symbolize_keys': You blew it, dumbass (RuntimeError) from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:45:in `resolve_hash_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:41:in `resolve_string_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:25:in `spec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:130:in `establish_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:82:in `block (2 levels) in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `instance_eval' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `execute_hook' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:26:in `block in on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:74:in `block in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `instance_exec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `run' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:55:in `block in run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/application.rb:136:in `initialize!' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/railtie/configurable.rb:30:in `method_missing' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/config/environment.rb:5:in `<top (required)>' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `require' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `<top

Friday, August 9, 13

Page 12: Code diving in Ruby and Rails

/Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/core_ext/hash/keys.rb:25:in `symbolize_keys': You blew it, dumbass (RuntimeError) from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:45:in `resolve_hash_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:41:in `resolve_string_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:25:in `spec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:130:in `establish_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:82:in `block (2 levels) in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `instance_eval' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:36:in `execute_hook' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:26:in `block in on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/lazy_load_hooks.rb:25:in `on_load' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/railtie.rb:74:in `block in <class:Railtie>' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `instance_exec' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:30:in `run' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:55:in `block in run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `each' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/initializable.rb:54:in `run_initializers' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/application.rb:136:in `initialize!' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/railties-3.2.12/lib/rails/railtie/configurable.rb:30:in `method_missing' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/config/environment.rb:5:in `<top (required)>' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `require' from /Volumes/Valinor/Users/evan/Development/Ruby/apps/tracks/spec/spec_helper.rb:3:in `<top

Friday, August 9, 13

Page 13: Code diving in Ruby and Rails

IT’S PROBABLY SOMETHING YOU DID.

Friday, August 9, 13

Page 14: Code diving in Ruby and Rails

IT’S PROBABLY SOMETHING YOU DID.

(but the error’s not in your code)

Friday, August 9, 13

Page 15: Code diving in Ruby and Rails

RAILS’ CODE ISHARD TO UNDERSTAND

Friday, August 9, 13

Page 16: Code diving in Ruby and Rails

RAILS’ CODE ISHARD TO UNDERSTAND

But that doesn’t matter!Dive in anyway.

Friday, August 9, 13

Page 17: Code diving in Ruby and Rails

RUBY IS A RUN-TIME LANGUAGE

Friday, August 9, 13

Page 18: Code diving in Ruby and Rails

RUBY IS A RUN-TIME LANGUAGE

•This makes it hard to find stuff!

Friday, August 9, 13

Page 19: Code diving in Ruby and Rails

RUBY IS A RUN-TIME LANGUAGE

•This makes it hard to find stuff!

•Your IDE isn’t much help

Friday, August 9, 13

Page 20: Code diving in Ruby and Rails

RUBY IS A RUN-TIME LANGUAGE

•This makes it hard to find stuff!

•Your IDE isn’t much help

•So find stuff AT RUN TIME

Friday, August 9, 13

Page 21: Code diving in Ruby and Rails

JUST OPEN THAT FILE

Friday, August 9, 13

Page 22: Code diving in Ruby and Rails

JUST OPEN THAT FILEDon’t be intimidated ... it’s all just Ruby

Friday, August 9, 13

Page 23: Code diving in Ruby and Rails

JUST OPEN THAT FILE

~/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/core_ext/hash/keys.rb:25:in `symbolize_keys': You blew it, dumbass (RuntimeError) from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:45:in `resolve_hash_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:41:in `resolve_string_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/

Don’t be intimidated ... it’s all just Ruby

Friday, August 9, 13

Page 24: Code diving in Ruby and Rails

JUST OPEN THAT FILE

~/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12/lib/active_support/core_ext/hash/keys.rb:25:in `symbolize_keys': You blew it, dumbass (RuntimeError) from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:45:in `resolve_hash_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb:41:in `resolve_string_connection' from /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/

$ vim ~evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/activesupport-3.2.12

Don’t be intimidated ... it’s all just Ruby

Friday, August 9, 13

Page 25: Code diving in Ruby and Rails

USE GEM...

Friday, August 9, 13

Page 26: Code diving in Ruby and Rails

USE GEM...$ gem env

Friday, August 9, 13

Page 27: Code diving in Ruby and Rails

USE GEM...RubyGems Environment: - RUBYGEMS VERSION: 1.8.25 - RUBY VERSION: 1.9.3 (2012-11-10 patchlevel 327) [x86_64-darwin11.4.2] - INSTALLATION DIRECTORY: /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fas - RUBY EXECUTABLE: /Volumes/Valinor/Users/evan/.rvm/rubies/ruby-1.9.3-p327-fast/bin/ - EXECUTABLE DIRECTORY: /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/bin - RUBYGEMS PLATFORMS: - ruby - x86_64-darwin-11 - GEM PATHS: - /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks - /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@global - GEM CONFIGURATION:

$ gem env

Friday, August 9, 13

Page 28: Code diving in Ruby and Rails

USE GEM...RubyGems Environment: - RUBYGEMS VERSION: 1.8.25 - RUBY VERSION: 1.9.3 (2012-11-10 patchlevel 327) [x86_64-darwin11.4.2] - INSTALLATION DIRECTORY: /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fas - RUBY EXECUTABLE: /Volumes/Valinor/Users/evan/.rvm/rubies/ruby-1.9.3-p327-fast/bin/ - EXECUTABLE DIRECTORY: /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/bin - RUBYGEMS PLATFORMS: - ruby - x86_64-darwin-11 - GEM PATHS: - /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks - /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@global - GEM CONFIGURATION:

$ gem env

Friday, August 9, 13

Page 29: Code diving in Ruby and Rails

USE GEM...RubyGems Environment: - RUBYGEMS VERSION: 1.8.25 - RUBY VERSION: 1.9.3 (2012-11-10 patchlevel 327) [x86_64-darwin11.4.2] - INSTALLATION DIRECTORY: /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fas - RUBY EXECUTABLE: /Volumes/Valinor/Users/evan/.rvm/rubies/ruby-1.9.3-p327-fast/bin/ - EXECUTABLE DIRECTORY: /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/bin - RUBYGEMS PLATFORMS: - ruby - x86_64-darwin-11 - GEM PATHS: - /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks - /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@global - GEM CONFIGURATION:

$ gem env

$ cd /Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks

Friday, August 9, 13

Page 30: Code diving in Ruby and Rails

ASK RUBY YOUR QUESTIONS!

Friday, August 9, 13

Page 31: Code diving in Ruby and Rails

WHAT’S THIS VALUE?#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols

Friday, August 9, 13

Page 32: Code diving in Ruby and Rails

WHAT’S THIS VALUE?#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols

Friday, August 9, 13

Page 33: Code diving in Ruby and Rails

WHAT’S THIS VALUE?#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys p self dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you

Friday, August 9, 13

Page 34: Code diving in Ruby and Rails

TOO MUCH OUTPUT!.{:client_id=>"24"}{"controller"=>"invoices", "action"=>"new"}.{:client_id=>"27"}{"controller"=>"invoices", "action"=>"new"}.{:client_id=>"30"}{"controller"=>"invoices", "action"=>"new"}.{:client_id=>"33"}{"controller"=>"invoices", "action"=>"new"}.{:client_id=>"37"}{"controller"=>"invoices", "action"=>"new"}.{:id=>"19"}{"id"=>"19", "controller"=>"invoices", "action"=>"edit"}.{:id=>"20"}{"id"=>"20", "controller"=>"invoices", "action"=>"edit"}{:controller=>"devise/sessions", :action=>"new", :use_route=>"login", :only_path=>true}.{:invoice=>{:due_on=>"2013-05-14", :client_id=>"42", :notes=>"value for notes"}}

Friday, August 9, 13

Page 35: Code diving in Ruby and Rails

OUTPUT AND STOP#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys raise self # stop running! dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you

Friday, August 9, 13

Page 36: Code diving in Ruby and Rails

ADD A CONDITION#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys raise self if <some condition> dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you

Friday, August 9, 13

Page 37: Code diving in Ruby and Rails

KEEP TRACK OF LOCATION#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys p __FILE__, __LINE__ dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you

Friday, August 9, 13

Page 38: Code diving in Ruby and Rails

LABEL WITH LOCATION#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys p “#{__FILE__}:#{__LINE__}” => self dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you

Friday, August 9, 13

Page 39: Code diving in Ruby and Rails

TAG WITH A NAME#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys p :broken_hash => self dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you

Friday, August 9, 13

Page 40: Code diving in Ruby and Rails

CLEAN IT UP#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys require ‘pp’ pp self dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.

Friday, August 9, 13

Page 41: Code diving in Ruby and Rails

OTHER USEFULQUESTIONS

Friday, August 9, 13

Page 42: Code diving in Ruby and Rails

HOW DID I GET HERE?

Friday, August 9, 13

Page 43: Code diving in Ruby and Rails

HOW DID I GET HERE?#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys require ‘pp’ pp caller[0..10] dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.

Friday, August 9, 13

Page 44: Code diving in Ruby and Rails

“DOES THIS FILE LOAD?”

module SomePossiblyIncludedMonkeyPatch def change_important_class_behavior # ... # ... end

def obscure_some_key_method # ... # ... end

end

Friday, August 9, 13

Page 45: Code diving in Ruby and Rails

“DOES THIS FILE LOAD?”raise “Yes, somebody required me”

module SomePossiblyIncludedMonkeyPatch def change_important_class_behavior # ... # ... end

def obscure_some_key_method # ... # ... end

end

Friday, August 9, 13

Page 46: Code diving in Ruby and Rails

“WHY DIDN’T THIS FILE LOAD?”

Friday, August 9, 13

Page 47: Code diving in Ruby and Rails

“WHY DIDN’T THIS FILE LOAD?”require ‘some_library/some_junk’

module MyNiftyBehavior def stuff

Friday, August 9, 13

Page 48: Code diving in Ruby and Rails

“WHY DIDN’T THIS FILE LOAD?”require ‘some_library/some_junk’

module MyNiftyBehavior def stuff

$ rspec spec/ No such file to load -- some_library/some_junk (LoadError)

Friday, August 9, 13

Page 49: Code diving in Ruby and Rails

“WHY DIDN’T THIS FILE LOAD?”require ‘some_library/some_junk’

module MyNiftyBehavior def stuff

$ rspec spec/ No such file to load -- some_library/some_junk (LoadError)

... pretty print the search path

Friday, August 9, 13

Page 50: Code diving in Ruby and Rails

“WHY DIDN’T THIS FILE LOAD?”require ‘some_library/some_junk’

module MyNiftyBehavior def stuff

$ rspec spec/ No such file to load -- some_library/some_junk (LoadError)

... pretty print the search pathrequire ‘pp’pp $:require ‘some_library/some_junk’

module MyNiftyBehavior def stuff

Friday, August 9, 13

Page 51: Code diving in Ruby and Rails

“WHO REQUIRED ME?”

module SomePossiblyIncludedMonkeyPatch def change_important_class_behavior # ... # ... end

def obscure_some_key_method # ... # ... end

end

Friday, August 9, 13

Page 52: Code diving in Ruby and Rails

“WHO REQUIRED ME?”p “Required By” => caller[0]

module SomePossiblyIncludedMonkeyPatch def change_important_class_behavior # ... # ... end

def obscure_some_key_method # ... # ... end

end

Friday, August 9, 13

Page 53: Code diving in Ruby and Rails

WHAT IF YOU DON’T KNOW THE RIGHT QUESTION YET?

Friday, August 9, 13

Page 54: Code diving in Ruby and Rails

USE DEBUGGER!

Friday, August 9, 13

Page 55: Code diving in Ruby and Rails

YOUR GEMFILEsource 'http://rubygems.org'

gem 'rails', '3.2.12'gem 'rack', '~> 1.4.0'

gem 'rake'gem "will_paginate"gem 'devise'

group :development, :test do gem 'rspec' gem 'rspec-rails' gem 'factory_girl_rails' gem 'debugger'end

Friday, August 9, 13

Page 56: Code diving in Ruby and Rails

IN THE CODEclass Hash # Return a new hash with all keys converted to symbols, as # long as they respond to +to_sym+. # # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys # #=> { :name => "Rob", :years => "28" } def symbolize_keys debugger dup.symbolize_keys! end

alias_method :to_options, :symbolize_keys alias_method :to_options!, :symbolize_keys!

# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols

Friday, August 9, 13

Page 57: Code diving in Ruby and Rails

RUNNING IT

Friday, August 9, 13

Page 58: Code diving in Ruby and Rails

RUNNING IT

$ rails server -u

Development Server:

Friday, August 9, 13

Page 59: Code diving in Ruby and Rails

RUNNING IT

$ rails server -u

Development Server:

$ rspec -d spec/

rSpec:

Friday, August 9, 13

Page 60: Code diving in Ruby and Rails

RUNNING IT

Arbitrary Ruby script:$ rdebug <command>

$ rdebug rake db:seed

Friday, August 9, 13

Page 61: Code diving in Ruby and Rails

WHO ARE YOU?#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash def symbolize_keys debugger dup.symbolize_keys! end

Friday, August 9, 13

Page 62: Code diving in Ruby and Rails

WHO ARE YOU?

(rdb:1) eval dup.class

#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash def symbolize_keys debugger dup.symbolize_keys! end

Friday, August 9, 13

Page 63: Code diving in Ruby and Rails

WHO ARE YOU?

(rdb:1) eval dup.class

Hash

#activesupport-3.2.12/lib/active_support/core_ext/hash class Hash def symbolize_keys debugger dup.symbolize_keys! end

Friday, August 9, 13

Page 64: Code diving in Ruby and Rails

WHO AM I?(rdb:1) eval self.class

Friday, August 9, 13

Page 65: Code diving in Ruby and Rails

WHO AM I?(rdb:1) eval self.class

Hash

Friday, August 9, 13

Page 66: Code diving in Ruby and Rails

WHO CAN I CALL?(rdb:1) eval self.methods

Friday, August 9, 13

Page 67: Code diving in Ruby and Rails

WHO CAN I CALL?(rdb:1) eval self.methods

[:specify, :class_variable_defined?, :public_class_method, :methods, :use_instantiated_fixtures=, :filtered_examples, :before_all_ivars, :should, :const_defined?, :untrust, :local_constant_names, :should_not, :capture, :module_eval, :instance_methods, :clone, :load_dependency, :to_json, :run_hook, :all_apply?, :share_examples_for, :include?, :redefine_method, :to_yaml, :respond_to?, :examples, :fail_fast?, :unloadable, :it_should_behave_like, :<=>, :instance_variable_defined?, :register, :acts_like?, :psych_yaml_as, :debug_method, :fixture_class_names, :let!, :render_views, :focus, :private_class_method, :delegate, :public_constant, :singleton_methods, :pretty_print_instance_variables, :attr_internal_writer, :use_instantiated_fixtures?, :matcher, :try, :tests, :as_json, :gem, :untrusted?, :controller_class, :pending, :parent, :silence, :class_eval,

Friday, August 9, 13

Page 68: Code diving in Ruby and Rails

WHO CAN I CALL?(rdb:1) eval self.methods.sort

Friday, August 9, 13

Page 69: Code diving in Ruby and Rails

WHO CAN I CALL?(rdb:1) eval self.methods.sort

[:!, :!=, :!~, :<=>, :==, :===, :=~, :[], :[]=, :__id__, :__send__, :`, :acts_like?, :all?, :any?, :as_json, :assert_valid_keys, :assoc, :binding_n, :blank?, :breakpoint, :capture, :chunk, :class, :class_eval, :clear, :clone, :collect, :collect_concat, :compare_by_identity, :compare_by_identity?, :count, :cycle, :dbg_print, :dbg_puts, :debugger, :deep_dup, :deep_merge, :deep_merge!, :deep_symbolize_keys, :default, :default=, :default_proc, :default_proc=, :define_singleton_method, :delete, :delete_if, :detect, :diff, :display, :drop, :drop_while, :dup, :duplicable?, :each, :each_cons, :each_entry, :each_key, :each_pair, :each_slice, :each_value, :each_with_index, :each_with_object, :empty?, :enable_warnings, :encode_json, :entries, :enum_for, :eql?, :equal?, :except, :except!, :exclude?, :extend, :extract!, :extractable_options?, :fetch, :find, :find_all, :find_index,

Friday, August 9, 13

Page 70: Code diving in Ruby and Rails

WHO CAN I CALL?(rdb:1) eval self.methods.grep(/merge/)

Friday, August 9, 13

Page 71: Code diving in Ruby and Rails

WHO CAN I CALL?(rdb:1) eval self.methods.grep(/merge/)

[:deep_merge!, :reverse_merge!, :merge!, :merge, :deep_merge, :reverse_merge, :merge_resultset]

Friday, August 9, 13

Page 72: Code diving in Ruby and Rails

DEBUGGER HAS ‘PP’ BY DEFAULT

Friday, August 9, 13

Page 73: Code diving in Ruby and Rails

WHO DO YOU INCLUDE?(rdb:1) pp dup.class.included_modules

Friday, August 9, 13

Page 74: Code diving in Ruby and Rails

WHO DO YOU INCLUDE?(rdb:1) pp dup.class.included_modules

[SimpleCov::HashMergeHelper, JSON::Ext::Generator::GeneratorMethods::Hash, Enumerable, RSpec::Steps::ClassMethods, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Dependencies::Loadable, PP::ObjectMixin, Kernel]

Friday, August 9, 13

Page 75: Code diving in Ruby and Rails

FINDINGMETHODS

Friday, August 9, 13

Page 76: Code diving in Ruby and Rails

AT THE COMMAND-LINE

-H (show filename)

-n (show line number)

-r (recurse directories)

-i (ignore case -- use carefully)

$ grep -Hnir <pattern> <path>

Friday, August 9, 13

Page 77: Code diving in Ruby and Rails

USEFUL PATTERNS

Friday, August 9, 13

Page 78: Code diving in Ruby and Rails

USEFUL PATTERNS

$ grep -Hnr “def *my_method” *

Method definitions:

Friday, August 9, 13

Page 79: Code diving in Ruby and Rails

USEFUL PATTERNS

$ grep -Hnr “def *my_method” *

Method definitions:

$ grep <stuff> | grep -v “ *#”

Ignore comments:

Friday, August 9, 13

Page 80: Code diving in Ruby and Rails

ACK > GREP$ ack <pattern>

Friday, August 9, 13

Page 81: Code diving in Ruby and Rails

ACK > GREP

Friday, August 9, 13

Page 82: Code diving in Ruby and Rails

ACK > GREP •Looks only in programming files (ignores

logs!)

Friday, August 9, 13

Page 83: Code diving in Ruby and Rails

ACK > GREP •Looks only in programming files (ignores

logs!)

•brew install ack

Friday, August 9, 13

Page 84: Code diving in Ruby and Rails

ACK > GREP •Looks only in programming files (ignores

logs!)

•brew install ack

•Configurable via .ackrc

Friday, August 9, 13

Page 85: Code diving in Ruby and Rails

ACK > GREP •Looks only in programming files (ignores

logs!)

•brew install ack

•Configurable via .ackrc

•https://gist.github.com/IdahoEv/5580770

Friday, August 9, 13

Page 86: Code diving in Ruby and Rails

BUT THEN THIS...

Friday, August 9, 13

Page 87: Code diving in Ruby and Rails

BUT THEN THIS...$ ack “def *my_method”

Friday, August 9, 13

Page 88: Code diving in Ruby and Rails

BUT THEN THIS...$ ack “def *my_method”$

Friday, August 9, 13

Page 89: Code diving in Ruby and Rails

BUT THEN THIS...$ ack “def *my_method”$

... it doesn’t exist

Friday, August 9, 13

Page 90: Code diving in Ruby and Rails

BUT THEN THIS...$ ack “def *my_method”$

... it doesn’t exist

Friday, August 9, 13

Page 91: Code diving in Ruby and Rails

BECAUSE RUBY LETS YOU DO THIS...

Friday, August 9, 13

Page 92: Code diving in Ruby and Rails

module RSpec module Core class ExampleGroup class << self

delegate_to_metadata :described_class, :file_path alias_method :display_name, :description alias_method :describes, :described_class

# @private # @macro [attach] define_example_method # @param [String] name # @param [Hash] extra_options # @param [Block] implementation def self.define_example_method(name, extra_options={}) module_eval(<<-END_RUBY, __FILE__, __LINE__) def #{name}(desc=nil, *args, &block) options = build_metadata_hash_from(args) options.update(:pending => RSpec::Core::Pending::) unless block options.update(#{extra_options.inspect}) examples << RSpec::Core::Example.new(self, desc, options, block) examples.last end END_RUBY end

define_example_method :example define_example_method :it define_example_method :specify

define_example_method :focus, :focused => true, :focus => true

Friday, August 9, 13

Page 93: Code diving in Ruby and Rails

module RSpec module Core class ExampleGroup class << self

delegate_to_metadata :described_class, :file_path alias_method :display_name, :description alias_method :describes, :described_class

# @private # @macro [attach] define_example_method # @param [String] name # @param [Hash] extra_options # @param [Block] implementation def self.define_example_method(name, extra_options={}) module_eval(<<-END_RUBY, __FILE__, __LINE__) def #{name}(desc=nil, *args, &block) options = build_metadata_hash_from(args) options.update(:pending => RSpec::Core::Pending::) unless block options.update(#{extra_options.inspect}) examples << RSpec::Core::Example.new(self, desc, options, block) examples.last end END_RUBY end

define_example_method :example define_example_method :it define_example_method :specify

define_example_method :focus, :focused => true, :focus => true

Friday, August 9, 13

Page 94: Code diving in Ruby and Rails

ADVANCED INTROSPECTION

Friday, August 9, 13

Page 95: Code diving in Ruby and Rails

WHO DO YOU INCLUDE?#activesupport-3.2.12/lib/active_support/core_ext/hash

class Hash # ... snip ... def symbolize_keys debugger dup.symbolize_keys! end # ... snip ...end

Friday, August 9, 13

Page 96: Code diving in Ruby and Rails

WHO DO YOU INCLUDE?(rdb:1) pp self.class.included_modules

[SimpleCov::HashMergeHelper, JSON::Ext::Generator::GeneratorMethods::Hash, Enumerable, RSpec::Steps::ClassMethods, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Dependencies::Loadable, PP::ObjectMixin, Kernel]

Friday, August 9, 13

Page 97: Code diving in Ruby and Rails

WHO DEFINED THAT METHOD?(rdb:1) eval self.method(:merge_resultset).owner

Friday, August 9, 13

Page 98: Code diving in Ruby and Rails

WHO DEFINED THAT METHOD?(rdb:1) eval self.method(:merge_resultset).owner

SimpleCov::HashMergeHelper

Friday, August 9, 13

Page 99: Code diving in Ruby and Rails

BUT DEFINED WHERE?(rdb:1) pp self.method(:merge_resultset).source_location

Friday, August 9, 13

Page 100: Code diving in Ruby and Rails

BUT DEFINED WHERE?(rdb:1) pp self.method(:merge_resultset).source_location

["~/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/simplecov-0.5.4/lib/simplecov/merge_helpers.rb", 25]

Friday, August 9, 13

Page 101: Code diving in Ruby and Rails

EVEN WORKS ON DYNAMIC METHODS!

Friday, August 9, 13

Page 102: Code diving in Ruby and Rails

EVEN WORKS ON DYNAMIC METHODS!

#/spec/controllers/invoices_controller_spec.rbrequire 'spec_helper'

describe InvoicesController do

debugger

describe "as an admin" do before(:each) do authenticate(:admin)

Friday, August 9, 13

Page 103: Code diving in Ruby and Rails

EVEN WORKS ON DYNAMIC METHODS!

(rdb:1) eval method(:example).source_location

Friday, August 9, 13

Page 104: Code diving in Ruby and Rails

EVEN WORKS ON DYNAMIC METHODS!

(rdb:1) eval method(:example).source_location

["/Volumes/Valinor/Users/evan/.rvm/gems/ruby-1.9.3-p327-fast@tracks/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb", 61]

Friday, August 9, 13

Page 105: Code diving in Ruby and Rails

WHERE TO LOOK NEXT•Pry (https://github.com/pry/pry)

•API Docs: http://www.ruby-doc.org/core-2.0

• Kernel

• Module

• Method

Friday, August 9, 13

Page 106: Code diving in Ruby and Rails

Thanks!

Evan DornFounder, Logical Reality Design

http://[email protected]

@idahoev

Text

Friday, August 9, 13


Recommended