12 hours to rate a rails application

2,762 views

Published on

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

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,762
On SlideShare
0
From Embeds
0
Number of Embeds
50
Actions
Shares
0
Downloads
20
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

12 hours to rate a rails application

  1. 1. hours to rate a Rails application Elise Huard @elise_huard http://jabberwocky.eu Tuesday 8 June 2010
  2. 2. Acquisition Tuesday 8 June 2010
  3. 3. Maintenance Tuesday 8 June 2010
  4. 4. 12 hours To Rate a Rails Application 12:00 Tuesday 8 June 2010
  5. 5. Team Tuesday 8 June 2010
  6. 6. One man’s application Tuesday 8 June 2010
  7. 7. Automator Control freak Innovator Tuesday 8 June 2010
  8. 8. ... Tuesday 8 June 2010
  9. 9. Vision vision photo by OneEighteen Tuesday 8 June 2010
  10. 10. Methodology Tuesday 8 June 2010
  11. 11. issue Tracker Version control docman on flickr Tuesday 8 June 2010
  12. 12. Back seat driver Tuesday 8 June 2010
  13. 13. 12 hours To Rate a Rails Application 10:00 Tuesday 8 June 2010
  14. 14. Try the app Björn Söderqvist on Flickr Tuesday 8 June 2010
  15. 15. does it work ? Tuesday 8 June 2010
  16. 16. 12 hours To Rate a Rails Application 09:45 Tuesday 8 June 2010
  17. 17. Rails version Tuesday 8 June 2010
  18. 18. plugins and gems Photo Lex on Flickr Tuesday 8 June 2010
  19. 19. Tuesday 8 June 2010
  20. 20. managing updates Bundler piston git submodules (svn externals) Tuesday 8 June 2010
  21. 21. Licenses BSD, MIT, Apache ... Tuesday 8 June 2010
  22. 22. NIH syndrom Tuesday 8 June 2010
  23. 23. Run Tests Tuesday 8 June 2010
  24. 24. 12 hours To Rate a Rails Application 09:00 Tuesday 8 June 2010
  25. 25. Lots of code Tuesday 8 June 2010
  26. 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. 27. models railroad -M | dot Tpng > models.png rubymine ctrl-alt-D Tuesday 8 June 2010
  28. 28. names “There are only two hard things in Computer Science: cache invalidation and naming things” Phil Karlton Tuesday 8 June 2010
  29. 29. 12 hours To Rate a Rails Application 08:30 Tuesday 8 June 2010
  30. 30. Metrics know thine tools docman on flickr Tuesday 8 June 2010
  31. 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. 32. RubyParser and Parsetree Ryan Davis and Eric Hodel (‘Ruby Sadists’) Tuesday 8 June 2010
  33. 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. 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. 35. RubyParser pure ruby Parsetree ruby and inline c < 1.9 swap out with Ripper ? Tuesday 8 June 2010
  36. 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. 37. flog ‘the pain your code is in’ Tuesday 8 June 2010
  38. 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. 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. 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. 41. FLOG Very good: < 20 All Right: < 50 Tuesday 8 June 2010
  42. 42. FLAY code similarities Tuesday 8 June 2010
  43. 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. 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. 45. Saikuro cyclomatic complexity Tuesday 8 June 2010
  46. 46. Saikuro Tuesday 8 June 2010
  47. 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. 48. Saikuro Good: methods < 5 Tuesday 8 June 2010
  49. 49. Roodi ‘Ruby Object Oriented Design Inferometer’ nutmeg66 on flickr Tuesday 8 June 2010
  50. 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. 51. Roodi RubyParser visitor pattern visitor: checker (Configurable) visitable: parsed nodes = extensible Tuesday 8 June 2010
  52. 52. Reek Tuesday 8 June 2010
  53. 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. 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. 55. Reek RubyParser extends parsed nodes traverses nodes returns code after Ruby2Ruby Tuesday 8 June 2010
  56. 56. rails_best_practices kamoda on Flickr Tuesday 8 June 2010
  57. 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. 58. rails_best_practices Visitor pattern visitor : checking_visitor visitable: visitable sexp Tuesday 8 June 2010
  59. 59. Churn Tuesday 8 June 2010
  60. 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. 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. 62. Churn common sense ... mostly useful in maintenance phase Tuesday 8 June 2010
  63. 63. Rcov Tuesday 8 June 2010
  64. 64. Rcov Total coverage: comments included Tuesday 8 June 2010
  65. 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. 66. Rcov good: 100% coverage Tuesday 8 June 2010
  67. 67. Heckle Tuesday 8 June 2010
  68. 68. Heckle ParseTree + Ruby2Ruby mutate Tuesday 8 June 2010
  69. 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. 70. Heckle time-consuming: combinatorials more for small programs (gems, scripts) doesn’t work for ruby 1.9 (ParseTree) Tuesday 8 June 2010
  71. 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. 72. metric_fu Tuesday 8 June 2010
  73. 73. what these metrics don’t tell you Bugs Tuesday 8 June 2010
  74. 74. what these metrics don’t tell you code performance Ruby Profiling Tuesday 8 June 2010
  75. 75. Reads like a book Tuesday 8 June 2010
  76. 76. 12 hours To Rate a Rails Application 06:30 Tuesday 8 June 2010
  77. 77. check out the good stuff OrbitalJoe on flickr Tuesday 8 June 2010
  78. 78. Database db/schema.rb seed data everything in migrations ? Tuesday 8 June 2010
  79. 79. views Bad: unindented divitis (too much) javascript in body too much logic in viewiew Tuesday 8 June 2010
  80. 80. 12 hours To Rate a Rails Application 04:30 Tuesday 8 June 2010
  81. 81. Tests Tuesday 8 June 2010
  82. 82. maintainable test suite tests = software changes in implementation changes in requirements Tuesday 8 June 2010
  83. 83. maintainable test suite express code responsibility hide implementation detail Tuesday 8 June 2010
  84. 84. maintainable test suite -> expressive code (DRY not mandatory) Tuesday 8 June 2010
  85. 85. 12 hours To Rate a Rails Application 02:30 Tuesday 8 June 2010
  86. 86. Deployment photo by devilarts on flickr Tuesday 8 June 2010
  87. 87. Deployment Tuesday 8 June 2010
  88. 88. Deployment Automation, automation, automation Tuesday 8 June 2010
  89. 89. Deployment deployment = software same rules apply Tuesday 8 June 2010
  90. 90. Deployment Traffic Performance tests Bottlenecks Tuesday 8 June 2010
  91. 91. 12 hours To Rate a Rails Application 01:00 Tuesday 8 June 2010
  92. 92. Brownie Points Tuesday 8 June 2010
  93. 93. Continuous integration ... and they’re using it Tuesday 8 June 2010
  94. 94. Documentation of any kind ... and it’s up to date Tuesday 8 June 2010
  95. 95. monitoring exception notification Log analyzers Tuesday 8 June 2010
  96. 96. testing javascript Continuous performance testing Tuesday 8 June 2010
  97. 97. 12 hours To Rate a Rails Application 00:00 Tuesday 8 June 2010
  98. 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

×