Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Eurucamp 2015: Deep Diving: How to Explore a new Codebase

Eurucamp 2015: Deep Diving: How to Explore a new Codebase

As a developer, diving in a new code base is not uncommon: you’ve just been hired, you change projects, you want to help an open source project, the open source library your project depends on is buggy, etc. It’s like swimming through a underwater cave, you don’t know what treasures or monsters you’ll find, if the path is treacherous, or if it’s a true labyrinth where you’ll get lost. However, if you plan your visit, you can prepare, equip yourself, and survive to find the gem you’re looking for…

code snippet to trace the whole call graph from a piece of code https://gist.github.com/toch/82fd93ca449500d21f00

Christophe Philemotte

August 01, 2015
Tweet

More Decks by Christophe Philemotte

Other Decks in Programming

Transcript

  1. • 300 dev days • 14633 LOC • 634595 Changed

    lines • → 634595 / 14633 ~ 43 changed LOC / LOC
  2. Plan 1. Goal 2. Map 3. Equipment & Dive 4.

    Next? Peter Southwood © 20011
  3. ➔ fix a bug ➔ implement a feature ➔ write

    some doc ➔ style the code ➔ refactor a small piece of code ➔ simply use it
  4. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:878:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED) from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:878:in `open'

    from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:878:in `block in connect' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/timeout.rb:52:in `timeout' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:877:in `connect' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:862:in `do_start' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:851:in `start' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:313:in `open_http' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:708:in `buffer_open' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:210:in `block in open_loo from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:208:in `catch' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:208:in `open_loop' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:149:in `open_uri' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:688:in `open' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:34:in `open' from -e:1:in `<main>'
  5. Find the Legend ➔ CONTRIBUTING Guideline ➔ Directory Structure ➔

    Talk to other contributors, maintainers ➔ Participate to the dev meeting
  6. Get a Toolbelt ➔ ST3 ➔ Apply a Patch &

    Use it ➔ MRI WIKI DeveloperHowto ➔ Sign up to Ruby Redmine
  7. $ wc -l *.rb 1001 common.rb 257 ftp.rb 1676 generic.rb

    106 http.rb 22 https.rb 260 ldap.rb 20 ldaps.rb 280 mailto.rb 3622 total open-uri
  8. def get_call_graph_on scope = {} trace = TracePoint.new(:call, :line) do

    |tp| case tp.event when :call then puts "#{tp.path}:#{tp.lineno} #{tp.defined_class}::#{tp.method_id} called from " \ "#{scope[:path]}:#{scope[:lineno]} #{scope[:class]}::#{scope[:method_id]}" when :line then scope = { event: :line, lineno: tp.lineno, path: tp.path, class: tp.defined_class, method_id: tp.method_id } end end trace.enable yield trace.disable end
  9. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:28 Kernel::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:746 #<Class:URI>::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:209 URI::Parser::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:120 URI::Parser::split ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:556 URI::Generic::split_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:617 URI::Generic::set_host ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:842 URI::Generic::set_path ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:907 URI::Generic::set_query ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:970 URI::Generic::set_opaque ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:779 URI::Generic::set_registry ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1013 URI::Generic::set_fragment ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port
  10. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:28 Kernel::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:746 #<Class:URI>::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:209 URI::Parser::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:120 URI::Parser::split ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:556 URI::Generic::split_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:617 URI::Generic::set_host ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:842 URI::Generic::set_path ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:907 URI::Generic::set_query ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:970 URI::Generic::set_opaque ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:779 URI::Generic::set_registry ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1013 URI::Generic::set_fragment ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port
  11. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:556 URI::Generic::split_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:617 URI::Generic::set_host ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:842 URI::Generic::set_path ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:907 URI::Generic::set_query ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:970 URI::Generic::set_opaque ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:779 URI::Generic::set_registry ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1013 URI::Generic::set_fragment ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:687 OpenURI::OpenRead::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:130 #<Class:OpenURI>::open_uri
  12. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:687 OpenURI::OpenRead::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:130 #<Class:OpenURI>::open_uri ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:120 #<Class:OpenURI>::scan_open_opt

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:111 #<Class:OpenURI>::check_options ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:166 #<Class:OpenURI>::open_loop ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:376 OpenURI::Buffer::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:707 URI::HTTP::buffer_open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:253 #<Class:OpenURI>::open_http ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:571 URI::Generic::userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3
  13. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:707 URI::HTTP::buffer_open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:253 #<Class:OpenURI>::open_http ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:571 URI::Generic::userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118

    #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3
  14. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:707 URI::HTTP::buffer_open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:253 #<Class:OpenURI>::open_http ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:571 URI::Generic::userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118

    #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3
  15. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168

    #<Clas Specification>::unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas Specification>::unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u
  16. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:660 URI::Generic::hostname ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:95 URI::HTTP::request_uri ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1442 URI::Generic::path_query

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:608 #<Class:Net::HTTP>::new ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:632 Net::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:993 #<Class:Net::HTTP>::proxy_class ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:847 Net::HTTP::start ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:861 Net::HTTP::do_start ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:867 Net::HTTP::connect ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1012 Net::HTTP::proxy? ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1026 Net::HTTP::proxy_uri ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:990 Kernel::URI ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:746 #<Class:URI>::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:209 URI::Parser::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:120 URI::Parser::split ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo
  17. Search the Source $ grep -nr "open_http". ./open-uri.rb:253: def OpenURI.open_http(buf,

    target, proxy, option ./open-uri.rb:708: OpenURI.open_http(buf, self, proxy, options) ./open-uri.rb:717: OpenURI.open_http(buf, self, proxy, option
  18. Search the Source $ grep -rn "class HTTP " .

    ./net/http.rb:384: class HTTP < Protocol ./uri/http.rb:22: class HTTP < Generic
  19. ➔ Trace the Calls ➔ Search the Source ➔ Get

    Context with a Test Dive into URI
  20. Get Context with a Test context "without params['markdown_img']" do it

    "returns an error" do get_call_graph_on do post :upload_image, id: project.to_param, format: :json end expect(response.status).to eq(422) end end
  21. Use your Toolbelt ➔ Run the App & Use it

    ➔ Read the Code ➔ Edit the Code
  22. Use your Toolbelt ➔ Run the App & Use it

    ➔ Read & Edit the Code ➔ Report a bug ➔ Submit a contribution
  23. Find Next Goal ➔ Fix a bug ➔ Develop a

    feature ➔ Run Static Analysis Tools ➔ Review a PullRequest