0
How to rate a
               Rails application

           Elise Huard @elise_huard
           http://jabberwocky.eu


Sun...
Acquisition
Sunday 30 May 2010
Maintenance


Sunday 30 May 2010
Where to Start ?




Sunday 30 May 2010
Try the app




                             Björn Söderqvist on Flickr

Sunday 30 May 2010
Rails version




Sunday 30 May 2010
plugins and
                    gems




                               Photo Lex on Flickr

Sunday 30 May 2010
Sunday 30 May 2010
Run Tests




Sunday 30 May 2010
Lots of code
Sunday 30 May 2010
config/routes.rb
                     match ‘/’, :to => ‘root#index’
                     match ‘root’, :to => ‘root#index...
models
                railroad -M | dot Tpng > models.png
                        rubymine ctrl-alt-D
Sunday 30 May 2010
names


                     “There are only two hard things in
                     Computer Science: cache
             ...
Metrics:
                     Know thine Tools


                                 docman on flickr
Sunday 30 May 2010
LOC
             rake stats
             +----------------------+-------+-------+---------+---------+-----+-------+
      ...
RubyParser and
                           Parsetree



                     Ryan Davis and Eric Hodel
                    ...
RubyParser and
                          Parsetree
                             Abstract syntax tree
            RubyParse...
RubyParser and
                          Parsetree
                             Abstract syntax tree
            RubyParse...
RubyParser

                        pure ruby

                       Parsetree
                     ruby and inline c
   ...
rake stats
                 size
        Flog                          Flay
           code complexity             code si...
flog
                     ‘the pain your code
                             is in’




Sunday 30 May 2010
FLOG
              flog lib/flog.rb
                 647.8: flog total
                  13.8: flog/method average

      ...
FLOG
                     Assignment Branch Condition (ABC)
                      def score_method(tally)
                ...
FLOG

                     Weighing the AST with factors
                      def process_if(exp)
                       ...
FLOG


                        Methods
                     Very good: < 20
                     All Right: < 50




Sunda...
FLAY
                     code similarities




Sunday 30 May 2010
FLAY
                     flay *.rb
                     Total score (lower is better) = 621

                     1) IDEN...
FLAY
          RubyParser
                 def mass
                   @mass ||= self.structure.flatten.size
             ...
Saikuro

                     cyclomatic
                     complexity
Sunday 30 May 2010
Saikuro




Sunday 30 May 2010
Saikuro
                           ruby-lex

               every keyword is interpreted into
                            ...
Saikuro




                        Good:
                     methods < 5




Sunday 30 May 2010
Roodi
           ‘Ruby Object Oriented Design Inferometer’




                                            nutmeg66 on flic...
Roodi


     app/controllers/itineraries_controller.rb:4 -   Method name "show" cyclomatic complexity
     is 14. It shoul...
Roodi


                     RubyParser
                     visitor pattern
                      visitor: checker (Confi...
Reek




Sunday 30 May 2010
Reek

                     more OO-specific checks
                     Control Couple
                     Data Clump
   ...
Reek

          UserSessionsController has no descriptive comment (Irresponsible Module)
          UserSessionsController#...
Reek



                              RubyParser
                         extends parsed nodes
                           ...
rails_best_practices




                                   kamoda on Flickr

Sunday 30 May 2010
rails_best_practices
  ./app/controllers/ws/vmg/aid_user_accounts_controller.rb:160 - move model logic into model
  (@aid_...
rails_best_practices


                           Visitor pattern
                     visitor : checking_visitor
        ...
Churn




Sunday 30 May 2010
Churn

                     +-------------------------------------------------+---------------+
                     | fil...
Churn



        Not only classes but also methods
                   (RubyParser)
           Version control: git, Hg, sv...
Churn



                              common sense ...
                     mostly useful in maintenance phase




Sunday...
Rcov
Sunday 30 May 2010
Rcov




               Total coverage: comments included




Sunday 30 May 2010
Rcov

                         Executes test
               keeps track of the executed lines
                Using C exte...
Rcov



                     good: 100% coverage




Sunday 30 May 2010
Heckle




Sunday 30 May 2010
Heckle

                        ParseTree + Ruby2Ruby
                                mutate

                     time-co...
Heckle
                     Initial tests pass. Let's rumble.

                     **************************************...
rake stats
                 size
        Flog                          Flay
           code complexity             code si...
metric_fu




Sunday 30 May 2010
check out the good stuff




                                           OrbitalJoe on flickr
Sunday 30 May 2010
what these metrics don’t
                             tell you



                              Bugs




Sunday 30 May 2010
what these metrics don’t
                             tell you



                         code performance
              ...
Reads like a book

Sunday 30 May 2010
http://railroad.rubyforge.org/
   http://www.igvita.com/2008/12/11/ruby-ast-for-fun-and-profit/
   http://ruby.sadi.st/Ruby...
Upcoming SlideShare
Loading in...5
×

how to rate a Rails application

4,073

Published on

Talk given at Euruko 2010: the talk describes how to quickly evaluate the quality of a Rails codebase. Ruby metrics are explained in detail.

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

No Downloads
Views
Total Views
4,073
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
29
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Transcript of "how to rate a Rails application"

  1. 1. How to rate a Rails application Elise Huard @elise_huard http://jabberwocky.eu Sunday 30 May 2010
  2. 2. Acquisition Sunday 30 May 2010
  3. 3. Maintenance Sunday 30 May 2010
  4. 4. Where to Start ? Sunday 30 May 2010
  5. 5. Try the app Björn Söderqvist on Flickr Sunday 30 May 2010
  6. 6. Rails version Sunday 30 May 2010
  7. 7. plugins and gems Photo Lex on Flickr Sunday 30 May 2010
  8. 8. Sunday 30 May 2010
  9. 9. Run Tests Sunday 30 May 2010
  10. 10. Lots of code Sunday 30 May 2010
  11. 11. 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] Sunday 30 May 2010 map.four_oh_four '*path' , :controller => 'four_oh_fours'
  12. 12. models railroad -M | dot Tpng > models.png rubymine ctrl-alt-D Sunday 30 May 2010
  13. 13. names “There are only two hard things in Computer Science: cache invalidation and naming things” Phil Karlton Sunday 30 May 2010
  14. 14. Metrics: Know thine Tools docman on flickr Sunday 30 May 2010
  15. 15. 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 Sunday 30 May 2010
  16. 16. RubyParser and Parsetree Ryan Davis and Eric Hodel (‘Ruby Sadists’) Sunday 30 May 2010
  17. 17. 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) Sunday 30 May 2010
  18. 18. 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 Sunday 30 May 2010
  19. 19. RubyParser pure ruby Parsetree ruby and inline c < 1.9 Sunday 30 May 2010
  20. 20. rake stats size Flog Flay code complexity code similarities Roodi R_B_P Saikuro Reek cyclomatic antipatterns Rails complexity Heckle Rcov test coverage Sunday 30 May 2010
  21. 21. flog ‘the pain your code is in’ Sunday 30 May 2010
  22. 22. 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 Sunday 30 May 2010
  23. 23. 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 Sunday 30 May 2010
  24. 24. 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 Sunday 30 May 2010
  25. 25. FLOG Methods Very good: < 20 All Right: < 50 Sunday 30 May 2010
  26. 26. FLAY code similarities Sunday 30 May 2010
  27. 27. 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 Sunday 30 May 2010
  28. 28. 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 Sunday 30 May 2010
  29. 29. Saikuro cyclomatic complexity Sunday 30 May 2010
  30. 30. Saikuro Sunday 30 May 2010
  31. 31. Saikuro ruby-lex every keyword is interpreted into ‘state’ state used to calculate if, unless, while, until, for, elsif, when, rescue (blocks) Recursively Sunday 30 May 2010
  32. 32. Saikuro Good: methods < 5 Sunday 30 May 2010
  33. 33. Roodi ‘Ruby Object Oriented Design Inferometer’ nutmeg66 on flickr Sunday 30 May 2010
  34. 34. 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. Sunday 30 May 2010
  35. 35. Roodi RubyParser visitor pattern visitor: checker (Configuration) visitable: parsed nodes = extensible Sunday 30 May 2010
  36. 36. Reek Sunday 30 May 2010
  37. 37. Reek more OO-specific checks Control Couple Data Clump Feature Envy Large Class Long Method Long Parameter List Simulated Polymorphism Uncommunicative Name Sunday 30 May 2010
  38. 38. 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) ... Sunday 30 May 2010
  39. 39. Reek RubyParser extends parsed nodes traverses nodes returns code after Ruby2Ruby Sunday 30 May 2010
  40. 40. rails_best_practices kamoda on Flickr Sunday 30 May 2010
  41. 41. 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 Sunday 30 May 2010
  42. 42. rails_best_practices Visitor pattern visitor : checking_visitor visitable: visitable sexp Sunday 30 May 2010
  43. 43. Churn Sunday 30 May 2010
  44. 44. 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 | ... Sunday 30 May 2010
  45. 45. Churn Not only classes but also methods (RubyParser) Version control: git, Hg, svn Locates changes in source using logs (as in git log) Sunday 30 May 2010
  46. 46. Churn common sense ... mostly useful in maintenance phase Sunday 30 May 2010
  47. 47. Rcov Sunday 30 May 2010
  48. 48. Rcov Total coverage: comments included Sunday 30 May 2010
  49. 49. Rcov Executes test keeps track of the executed lines Using C extension when possible to hook into MRI (experimental for 1.9) Sunday 30 May 2010
  50. 50. Rcov good: 100% coverage Sunday 30 May 2010
  51. 51. Heckle Sunday 30 May 2010
  52. 52. Heckle ParseTree + Ruby2Ruby mutate time-consuming: combinatorials more for small programs (gems, scripts) doesn’t work for ruby 1.9 (ParseTree) Sunday 30 May 2010
  53. 53. 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 Sunday 30 May 2010
  54. 54. rake stats size Flog Flay code complexity code similarities Roodi Saikuro Reek cyclomatic antipatterns RAILS_BEST complexity _PRACTICES Heckle Rcov test coverage Sunday 30 May 2010
  55. 55. metric_fu Sunday 30 May 2010
  56. 56. check out the good stuff OrbitalJoe on flickr Sunday 30 May 2010
  57. 57. what these metrics don’t tell you Bugs Sunday 30 May 2010
  58. 58. what these metrics don’t tell you code performance Ruby Profiling Sunday 30 May 2010
  59. 59. Reads like a book Sunday 30 May 2010
  60. 60. 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 http://github.com/elisehuard Sunday 30 May 2010
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×