106
Code Diving in Ruby Evan Dorn Founder, Logical Reality Design http://lrdesign.com [email protected] @idahoev Friday, August 9, 13

Code diving in Ruby and Rails

Embed Size (px)

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.

Citation preview

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