12 hours to rate a rails application
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

12 hours to rate a rails application

  • 3,045 views
Uploaded on

improved version of 12 hours to rate a rails application - modified after feedback from Euruko and ScotRuby. ...

improved version of 12 hours to rate a rails application - modified after feedback from Euruko and ScotRuby.
As presented at Railsconf

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,045
On Slideshare
2,996
From Embeds
49
Number of Embeds
2

Actions

Shares
Downloads
18
Comments
0
Likes
5

Embeds 49

http://www.slideshare.net 47
https://twitter.com 2

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. hours to rate a Rails application Elise Huard @elise_huard http://jabberwocky.eu Tuesday 8 June 2010
  • 2. Acquisition Tuesday 8 June 2010
  • 3. Maintenance Tuesday 8 June 2010
  • 4. 12 hours To Rate a Rails Application 12:00 Tuesday 8 June 2010
  • 5. Team Tuesday 8 June 2010
  • 6. One man’s application Tuesday 8 June 2010
  • 7. Automator Control freak Innovator Tuesday 8 June 2010
  • 8. ... Tuesday 8 June 2010
  • 9. Vision vision photo by OneEighteen Tuesday 8 June 2010
  • 10. Methodology Tuesday 8 June 2010
  • 11. issue Tracker Version control docman on flickr Tuesday 8 June 2010
  • 12. Back seat driver Tuesday 8 June 2010
  • 13. 12 hours To Rate a Rails Application 10:00 Tuesday 8 June 2010
  • 14. Try the app Björn Söderqvist on Flickr Tuesday 8 June 2010
  • 15. does it work ? Tuesday 8 June 2010
  • 16. 12 hours To Rate a Rails Application 09:45 Tuesday 8 June 2010
  • 17. Rails version Tuesday 8 June 2010
  • 18. plugins and gems Photo Lex on Flickr Tuesday 8 June 2010
  • 19. Tuesday 8 June 2010
  • 20. managing updates Bundler piston git submodules (svn externals) Tuesday 8 June 2010
  • 21. Licenses BSD, MIT, Apache ... Tuesday 8 June 2010
  • 22. NIH syndrom Tuesday 8 June 2010
  • 23. Run Tests Tuesday 8 June 2010
  • 24. 12 hours To Rate a Rails Application 09:00 Tuesday 8 June 2010
  • 25. Lots of code Tuesday 8 June 2010
  • 26. config/routes.rb match ‘/’, :to => ‘root#index’ match ‘root’, :to => ‘root#index’ namespace :admin do resources :grids do resources :nodes resources :edges do collection do post :all post :update_all end end resources :walkers end end resources :nodes, :only => [:show,:new,:create,:destroy] do put :directions, :on => :collection end resources :walkers, :only => [:show,:new,:create,:destroy] do get :select, :on => :collection end resources :itineraries, :only => [:show] Tuesday 8 June 2010 map.four_oh_four '*path' , :controller => 'four_oh_fours'
  • 27. models railroad -M | dot Tpng > models.png rubymine ctrl-alt-D Tuesday 8 June 2010
  • 28. names “There are only two hard things in Computer Science: cache invalidation and naming things” Phil Karlton Tuesday 8 June 2010
  • 29. 12 hours To Rate a Rails Application 08:30 Tuesday 8 June 2010
  • 30. Metrics know thine tools docman on flickr Tuesday 8 June 2010
  • 31. LOC rake stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 2702 | 2150 | 36 | 158 | 4 | 11 | | Helpers | 358 | 303 | 0 | 22 | 0 | 11 | | Models | 1358 | 1104 | 30 | 117 | 3 | 7 | | Libraries | 2286 | 1655 | 38 | 152 | 4 | 8 | | Integration tests | 0 | 0 | 0 | 0 | 0 | 0 | | Functional tests | 1687 | 1322 | 31 | 195 | 6 | 4 | | Unit tests | 1356 | 1079 | 27 | 158 | 5 | 4 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | 9747 | 7613 | 162 | 802 | 4 | 7 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 5212 Test LOC: 2401 Code to Test Ratio: 1:0.5 Tuesday 8 June 2010
  • 32. RubyParser and Parsetree Ryan Davis and Eric Hodel (‘Ruby Sadists’) Tuesday 8 June 2010
  • 33. RubyParser and Parsetree Abstract syntax tree RubyParser.new.parse(File.read(‘metrics.rb’),‘metric.rb’) class Metrics s(:class,:Metrics, nil, def probe s(:scope, s(:defn,:probe, puts "good" s(:args), end s(:scope, end s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "good")))))))) Symbolic Expression (Sexp) Tuesday 8 June 2010
  • 34. RubyParser and Parsetree Abstract syntax tree RubyParser.new.parse(File.read(‘metrics.rb’),‘metric.rb’) class Metrics s(:class,:Metrics, nil, def probe s(:scope, s(:defn,:probe, puts "good" s(:args), end s(:scope, end s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "good")))))))) Symbolic Expression (Sexp) Ruby2Ruby Tuesday 8 June 2010
  • 35. RubyParser pure ruby Parsetree ruby and inline c < 1.9 swap out with Ripper ? Tuesday 8 June 2010
  • 36. rake stats size Flog Flay code complexity code similarities Roodi R_B_P Saikuro Reek cyclomatic antipatterns Rails complexity Heckle Rcov test coverage Tuesday 8 June 2010
  • 37. flog ‘the pain your code is in’ Tuesday 8 June 2010
  • 38. FLOG flog lib/flog.rb 647.8: flog total 13.8: flog/method average 87.5: Flog#output_details 58.8: Flog#process_iter 54.2: Flog#flog 48.8: Flog#parse_options 34.1: Flog#none 23.2: Flog#output_method_details 22.1: Flog#score_method 16.0: Flog#process_block_pass 15.6: Flog#report 15.2: Flog#expand_dirs_to_files 15.0: Flog#klass_name Tuesday 8 June 2010
  • 39. FLOG Assignment Branch Condition (ABC) def score_method(tally) a, b, c = 0, 0, 0 tally.each do |cat, score| case cat when :assignment then a += score when :branch then b += score else c += score end end Math.sqrt(a*a + b*b + c*c) end Tuesday 8 June 2010
  • 40. FLOG Weighing the AST with factors def process_if(exp) add_to_score :branch process exp.shift # cond penalize_by 0.1 do process exp.shift # true process exp.shift # false end s() end Tuesday 8 June 2010
  • 41. FLOG Very good: < 20 All Right: < 50 Tuesday 8 June 2010
  • 42. FLAY code similarities Tuesday 8 June 2010
  • 43. FLAY flay *.rb Total score (lower is better) = 621 1) IDENTICAL code found in :defn (mass*2 = 188) channel.rb:48 clip.rb:80 2) Similar code found in :defn (mass = 93) channel.rb:150 clip.rb:110 clip.rb:116 3) Similar code found in :defs (mass = 58) contact.rb:32 contact.rb:37 Tuesday 8 June 2010
  • 44. FLAY RubyParser def mass @mass ||= self.structure.flatten.size end Hash of structure of nodes with mass > threshold self.hashes[node.structural_hash] << node analyze: if same hash = similar if same node = identical Tuesday 8 June 2010
  • 45. Saikuro cyclomatic complexity Tuesday 8 June 2010
  • 46. Saikuro Tuesday 8 June 2010
  • 47. Saikuro ruby-lex every keyword is interpreted into ‘state’ state used to calculate if, unless, while, until, for, elsif, when, rescue (blocks) Recursively Tuesday 8 June 2010
  • 48. Saikuro Good: methods < 5 Tuesday 8 June 2010
  • 49. Roodi ‘Ruby Object Oriented Design Inferometer’ nutmeg66 on flickr Tuesday 8 June 2010
  • 50. Roodi app/controllers/itineraries_controller.rb:4 - Method name "show" cyclomatic complexity is 14. It should be 8 or less. app/models/itinerary.rb:41 - Block cyclomatic complexity is 6. It should be 4 or less. app/controllers/itineraries_controller.rb:4 - Method "show" has 30 lines. It should have 20 or less. app/helpers/application_helper.rb:27 - Method "clippy" has 26 lines. It should have 20 or less. Tuesday 8 June 2010
  • 51. Roodi RubyParser visitor pattern visitor: checker (Configurable) visitable: parsed nodes = extensible Tuesday 8 June 2010
  • 52. Reek Tuesday 8 June 2010
  • 53. Reek UserSessionsController has no descriptive comment (Irresponsible Module) UserSessionsController#destroy calls current_user_session twice (Duplication) app/controllers/users_controller.rb -- 5 warnings: UsersController has no descriptive comment (Irresponsible Module) UsersController tests @aid_app at least 4 times (Simulated Polymorphism) UsersController#create calls params 3 times (Duplication) UsersController#create calls params[:user] 3 times (Duplication) ... Tuesday 8 June 2010
  • 54. Reek OO Code smells Control Couple Data Clump Feature Envy Large Class Long Method Long Parameter List Simulated Polymorphism Uncommunicative Name Tuesday 8 June 2010
  • 55. Reek RubyParser extends parsed nodes traverses nodes returns code after Ruby2Ruby Tuesday 8 June 2010
  • 56. rails_best_practices kamoda on Flickr Tuesday 8 June 2010
  • 57. rails_best_practices ./app/controllers/ws/vmg/aid_user_accounts_controller.rb:160 - move model logic into model (@aid_user_account called_count > 4) ./app/controllers/ws/vmg/ipt_controller.rb:102 - move model logic into model (xml called_count > 4) ./app/controllers/ws/vmg/ipt_controller.rb:102 - move model logic into model (pf called_count > 4) ./config/routes.rb:3 - overuse route customizations (customize_count > 3) ./config/routes.rb:35 - overuse route customizations (customize_count > 3) ./app/models/vmg/scenario.rb:41 - keep finders on their own model Tuesday 8 June 2010
  • 58. rails_best_practices Visitor pattern visitor : checking_visitor visitable: visitable sexp Tuesday 8 June 2010
  • 59. Churn Tuesday 8 June 2010
  • 60. Churn Not only classes but also methods (RubyParser) Version control: git, Hg, svn Locates changes in source using logs (as in git log) Tuesday 8 June 2010
  • 61. Churn +-------------------------------------------------+---------------+ | file_path | times_changed | +-------------------------------------------------+---------------+ | db/schema.rb | 26 | | config/routes.rb | 24 | | app/controllers/application_controller.rb | 22 | | app/controllers/add_apps_controller.rb | 22 | | config/environment.rb | 20 | | app/views/layouts/application.html.erb | 20 | | app/models/ability.rb | 18 | ... Tuesday 8 June 2010
  • 62. Churn common sense ... mostly useful in maintenance phase Tuesday 8 June 2010
  • 63. Rcov Tuesday 8 June 2010
  • 64. Rcov Total coverage: comments included Tuesday 8 June 2010
  • 65. Rcov Executes test keeps track of the executed lines Using C extension when possible to hook into MRI (experimental for 1.9) Tuesday 8 June 2010
  • 66. Rcov good: 100% coverage Tuesday 8 June 2010
  • 67. Heckle Tuesday 8 June 2010
  • 68. Heckle ParseTree + Ruby2Ruby mutate Tuesday 8 June 2010
  • 69. Heckle Initial tests pass. Let's rumble. ********************************************************************** *** AidApp#property_names loaded with 4 possible mutations ********************************************************************** 4 mutations remaining... Replacing AidApp#property_names with: --- original +++ mutation def property_names - (meta_policy and meta_policy.property_names_for(:aid_app)) + (nil and meta_policy.property_names_for(:aid_app)) end Tuesday 8 June 2010
  • 70. Heckle time-consuming: combinatorials more for small programs (gems, scripts) doesn’t work for ruby 1.9 (ParseTree) Tuesday 8 June 2010
  • 71. rake stats size Flog Flay code complexity code similarities Roodi R_B_P Saikuro Reek cyclomatic antipatterns Rails complexity Heckle Rcov test coverage Tuesday 8 June 2010
  • 72. metric_fu Tuesday 8 June 2010
  • 73. what these metrics don’t tell you Bugs Tuesday 8 June 2010
  • 74. what these metrics don’t tell you code performance Ruby Profiling Tuesday 8 June 2010
  • 75. Reads like a book Tuesday 8 June 2010
  • 76. 12 hours To Rate a Rails Application 06:30 Tuesday 8 June 2010
  • 77. check out the good stuff OrbitalJoe on flickr Tuesday 8 June 2010
  • 78. Database db/schema.rb seed data everything in migrations ? Tuesday 8 June 2010
  • 79. views Bad: unindented divitis (too much) javascript in body too much logic in viewiew Tuesday 8 June 2010
  • 80. 12 hours To Rate a Rails Application 04:30 Tuesday 8 June 2010
  • 81. Tests Tuesday 8 June 2010
  • 82. maintainable test suite tests = software changes in implementation changes in requirements Tuesday 8 June 2010
  • 83. maintainable test suite express code responsibility hide implementation detail Tuesday 8 June 2010
  • 84. maintainable test suite -> expressive code (DRY not mandatory) Tuesday 8 June 2010
  • 85. 12 hours To Rate a Rails Application 02:30 Tuesday 8 June 2010
  • 86. Deployment photo by devilarts on flickr Tuesday 8 June 2010
  • 87. Deployment Tuesday 8 June 2010
  • 88. Deployment Automation, automation, automation Tuesday 8 June 2010
  • 89. Deployment deployment = software same rules apply Tuesday 8 June 2010
  • 90. Deployment Traffic Performance tests Bottlenecks Tuesday 8 June 2010
  • 91. 12 hours To Rate a Rails Application 01:00 Tuesday 8 June 2010
  • 92. Brownie Points Tuesday 8 June 2010
  • 93. Continuous integration ... and they’re using it Tuesday 8 June 2010
  • 94. Documentation of any kind ... and it’s up to date Tuesday 8 June 2010
  • 95. monitoring exception notification Log analyzers Tuesday 8 June 2010
  • 96. testing javascript Continuous performance testing Tuesday 8 June 2010
  • 97. 12 hours To Rate a Rails Application 00:00 Tuesday 8 June 2010
  • 98. http://railroad.rubyforge.org/ http://www.igvita.com/2008/12/11/ruby-ast-for-fun-and-profit/ http://ruby.sadi.st/Ruby_Sadist.html http://goruco2008.confreaks.com/04_davis.html http://cwd.dhemery.com/2009/11/wmaat/ http://c2.com/cgi/wiki?AbcMetric http://hissa.nist.gov/HHRFdata/Artifacts/ITLdoc/235/title.htm http://blog.rubybestpractices.com/posts/judofyr/sexp-for- rubyists.html Elise Huard @elise_huard elise@elisehuard.be http://jabberwocky.eu Tuesday 8 June 2010