Code diving in Ruby and Rails

1,487 views

Published on

Finding your way through foreign spaghetti code can be challenging. Learn to use Ruby's introspection tools to fearlessly code dive like a pro.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,487
On SlideShare
0
From Embeds
0
Number of Embeds
27
Actions
Shares
0
Downloads
8
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Code diving in Ruby and Rails

  1. 1. Code Diving in Ruby Evan Dorn Founder, Logical Reality Design http://lrdesign.com evan@lrdesign.com @idahoev Friday, August 9, 13
  2. 2. SO YOU’RE CODING ALONG WHEN... Friday, August 9, 13
  3. 3. 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
  4. 4. AND YOU’RE LIKE Friday, August 9, 13
  5. 5. BUT THEN YOU NOTICE THIS... Friday, August 9, 13
  6. 6. 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
  7. 7. 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
  8. 8. BUT WHAT ABOUT WHEN... Friday, August 9, 13
  9. 9. /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
  10. 10. /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
  11. 11. /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
  12. 12. /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
  13. 13. IT’S PROBABLY SOMETHING YOU DID. Friday, August 9, 13
  14. 14. IT’S PROBABLY SOMETHING YOU DID. (but the error’s not in your code) Friday, August 9, 13
  15. 15. RAILS’ CODE IS HARD TO UNDERSTAND Friday, August 9, 13
  16. 16. RAILS’ CODE IS HARD TO UNDERSTAND But that doesn’t matter! Dive in anyway. Friday, August 9, 13
  17. 17. RUBY IS A RUN-TIME LANGUAGE Friday, August 9, 13
  18. 18. RUBY IS A RUN-TIME LANGUAGE •This makes it hard to find stuff! Friday, August 9, 13
  19. 19. RUBY IS A RUN-TIME LANGUAGE •This makes it hard to find stuff! •Your IDE isn’t much help Friday, August 9, 13
  20. 20. 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
  21. 21. JUST OPEN THAT FILE Friday, August 9, 13
  22. 22. JUST OPEN THAT FILE Don’t be intimidated ... it’s all just Ruby Friday, August 9, 13
  23. 23. 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
  24. 24. 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
  25. 25. USE GEM... Friday, August 9, 13
  26. 26. USE GEM... $ gem env Friday, August 9, 13
  27. 27. 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
  28. 28. 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
  29. 29. 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
  30. 30. ASK RUBY YOUR QUESTIONS! Friday, August 9, 13
  31. 31. 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
  32. 32. 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
  33. 33. 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
  34. 34. 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
  35. 35. 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
  36. 36. 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
  37. 37. 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
  38. 38. 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
  39. 39. 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
  40. 40. 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
  41. 41. OTHER USEFUL QUESTIONS Friday, August 9, 13
  42. 42. HOW DID I GET HERE? Friday, August 9, 13
  43. 43. 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
  44. 44. “DOES THIS FILE LOAD?” module SomePossiblyIncludedMonkeyPatch def change_important_class_behavior # ... # ... end def obscure_some_key_method # ... # ... end end Friday, August 9, 13
  45. 45. “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
  46. 46. “WHY DIDN’T THIS FILE LOAD?” Friday, August 9, 13
  47. 47. “WHY DIDN’T THIS FILE LOAD?” require ‘some_library/some_junk’ module MyNiftyBehavior def stuff Friday, August 9, 13
  48. 48. “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
  49. 49. “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
  50. 50. “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 require ‘pp’ pp $: require ‘some_library/some_junk’ module MyNiftyBehavior def stuff Friday, August 9, 13
  51. 51. “WHO REQUIRED ME?” module SomePossiblyIncludedMonkeyPatch def change_important_class_behavior # ... # ... end def obscure_some_key_method # ... # ... end end Friday, August 9, 13
  52. 52. “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
  53. 53. WHAT IF YOU DON’T KNOW THE RIGHT QUESTION YET? Friday, August 9, 13
  54. 54. USE DEBUGGER! Friday, August 9, 13
  55. 55. YOUR GEMFILE source '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
  56. 56. IN THE CODE 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 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
  57. 57. RUNNING IT Friday, August 9, 13
  58. 58. RUNNING IT $ rails server -u Development Server: Friday, August 9, 13
  59. 59. RUNNING IT $ rails server -u Development Server: $ rspec -d spec/ rSpec: Friday, August 9, 13
  60. 60. RUNNING IT Arbitrary Ruby script: $ rdebug <command> $ rdebug rake db:seed Friday, August 9, 13
  61. 61. 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
  62. 62. 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
  63. 63. 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
  64. 64. WHO AM I? (rdb:1) eval self.class Friday, August 9, 13
  65. 65. WHO AM I? (rdb:1) eval self.class Hash Friday, August 9, 13
  66. 66. WHO CAN I CALL? (rdb:1) eval self.methods Friday, August 9, 13
  67. 67. 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
  68. 68. WHO CAN I CALL? (rdb:1) eval self.methods.sort Friday, August 9, 13
  69. 69. 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
  70. 70. WHO CAN I CALL? (rdb:1) eval self.methods.grep(/merge/) Friday, August 9, 13
  71. 71. 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
  72. 72. DEBUGGER HAS ‘PP’ BY DEFAULT Friday, August 9, 13
  73. 73. WHO DO YOU INCLUDE? (rdb:1) pp dup.class.included_modules Friday, August 9, 13
  74. 74. 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
  75. 75. FINDING METHODS Friday, August 9, 13
  76. 76. 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
  77. 77. USEFUL PATTERNS Friday, August 9, 13
  78. 78. USEFUL PATTERNS $ grep -Hnr “def *my_method” * Method definitions: Friday, August 9, 13
  79. 79. USEFUL PATTERNS $ grep -Hnr “def *my_method” * Method definitions: $ grep <stuff> | grep -v “ *#” Ignore comments: Friday, August 9, 13
  80. 80. ACK > GREP $ ack <pattern> Friday, August 9, 13
  81. 81. ACK > GREP Friday, August 9, 13
  82. 82. ACK > GREP •Looks only in programming files (ignores logs!) Friday, August 9, 13
  83. 83. ACK > GREP •Looks only in programming files (ignores logs!) •brew install ack Friday, August 9, 13
  84. 84. ACK > GREP •Looks only in programming files (ignores logs!) •brew install ack •Configurable via .ackrc Friday, August 9, 13
  85. 85. 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
  86. 86. BUT THEN THIS... Friday, August 9, 13
  87. 87. BUT THEN THIS... $ ack “def *my_method” Friday, August 9, 13
  88. 88. BUT THEN THIS... $ ack “def *my_method” $ Friday, August 9, 13
  89. 89. BUT THEN THIS... $ ack “def *my_method” $ ... it doesn’t exist Friday, August 9, 13
  90. 90. BUT THEN THIS... $ ack “def *my_method” $ ... it doesn’t exist Friday, August 9, 13
  91. 91. BECAUSE RUBY LETS YOU DO THIS... Friday, August 9, 13
  92. 92. 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
  93. 93. 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
  94. 94. ADVANCED INTROSPECTION Friday, August 9, 13
  95. 95. 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
  96. 96. 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
  97. 97. WHO DEFINED THAT METHOD? (rdb:1) eval self.method(:merge_resultset).owner Friday, August 9, 13
  98. 98. WHO DEFINED THAT METHOD? (rdb:1) eval self.method(:merge_resultset).owner SimpleCov::HashMergeHelper Friday, August 9, 13
  99. 99. BUT DEFINED WHERE? (rdb:1) pp self.method(:merge_resultset).source_location Friday, August 9, 13
  100. 100. 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
  101. 101. EVEN WORKS ON DYNAMIC METHODS! Friday, August 9, 13
  102. 102. EVEN WORKS ON DYNAMIC METHODS! #/spec/controllers/invoices_controller_spec.rb require 'spec_helper' describe InvoicesController do debugger describe "as an admin" do before(:each) do authenticate(:admin) Friday, August 9, 13
  103. 103. EVEN WORKS ON DYNAMIC METHODS! (rdb:1) eval method(:example).source_location Friday, August 9, 13
  104. 104. 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
  105. 105. 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
  106. 106. Thanks! Evan Dorn Founder, Logical Reality Design http://lrdesign.com evan@lrdesign.com @idahoev Text Friday, August 9, 13

×