hours to rate a Rails application
Elise Huard @elise_huardhttp://jabberwocky.eu
Tuesday 8 June 2010
Acquisition
Tuesday 8 June 2010
Maintenance
Tuesday 8 June 2010
12 hours To Rate a Rails Application
12:00
Tuesday 8 June 2010
Team
Tuesday 8 June 2010
One man’s application
Tuesday 8 June 2010
Maintenance
Maintenance
Innovator
Automator
Control freak
Tuesday 8 June 2010
...
Tuesday 8 June 2010
Vision
photo by OneEighteen
vision
Tuesday 8 June 2010
Methodology
Tuesday 8 June 2010
docman on flickr
issue TrackerVersion control
Tuesday 8 June 2010
Back seat driver
Tuesday 8 June 2010
10:00
12 hours To Rate a Rails Application
Tuesday 8 June 2010
Try the app
Björn Söderqvist on Flickr
Tuesday 8 June 2010
does it work ?
Tuesday 8 June 2010
09:45
12 hours To Rate a Rails Application
Tuesday 8 June 2010
Rails version
Tuesday 8 June 2010
plugins and gems
Photo Lex on Flickr
Tuesday 8 June 2010
Tuesday 8 June 2010
managing updatesBundlerpiston
git submodules(svn externals)
Tuesday 8 June 2010
LicensesBSD, MIT, Apache ...
Tuesday 8 June 2010
NIH syndrom
Tuesday 8 June 2010
Run Tests
Tuesday 8 June 2010
09:00
12 hours To Rate a Rails Application
Tuesday 8 June 2010
Lots of code
Tuesday 8 June 2010
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 endend resources :nodes, :only => [:show,:new,:create,:destroy] do put :directions, :on => :collectionend
resources :walkers, :only => [:show,:new,:create,:destroy] do get :select, :on => :collectionendresources :itineraries, :only => [:show]
map.four_oh_four '*path' , :controller => 'four_oh_fours'Tuesday 8 June 2010
modelsrailroad -M | dot Tpng > models.png
rubymine ctrl-alt-D
Tuesday 8 June 2010
names
“There are only two hard things in Computer Science: cache invalidation and naming things”
Phil Karlton
Tuesday 8 June 2010
08:30
12 hours To Rate a Rails Application
Tuesday 8 June 2010
Metricsknow thine tools
docman on flickr
Tuesday 8 June 2010
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
RubyParser and Parsetree
Ryan Davis and Eric Hodel(‘Ruby Sadists’)
Tuesday 8 June 2010
RubyParser and Parsetree
Abstract syntax treeRubyParser.new.parse(File.read(‘metrics.rb’),‘metric.rb’)
class Metrics def probe puts "good" end end
s(:class,:Metrics, nil, s(:scope, s(:defn,:probe, s(:args), s(:scope, s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "good"))))))))
Symbolic Expression (Sexp)
Tuesday 8 June 2010
RubyParser and Parsetree
Abstract syntax treeRubyParser.new.parse(File.read(‘metrics.rb’),‘metric.rb’)
class Metrics def probe puts "good" end end
s(:class,:Metrics, nil, s(:scope, s(:defn,:probe, s(:args), s(:scope, s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "good"))))))))
Symbolic Expression (Sexp)
Ruby2Ruby
Tuesday 8 June 2010
RubyParser
Parsetree
pure ruby
ruby and inline c< 1.9
swap out with Ripper ?
Tuesday 8 June 2010
cyclomatic complexity
size
code complexity code similarities
test coverage
antipatterns
rake stats
Flay
ReekRoodi
Flog
Saikuro
Heckle Rcov
Rails
R_B_P
Tuesday 8 June 2010
flog‘the pain your code
is in’
Tuesday 8 June 2010
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
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
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
FLOG
Very good: < 20All Right: < 50
Tuesday 8 June 2010
FLAYcode similarities
Tuesday 8 June 2010
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
FLAY
Tuesday 8 June 2010
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 = similarif same node = identical
FLAY
Tuesday 8 June 2010
Saikuroサイクロ
cyclomatic complexity
Tuesday 8 June 2010
Saikuro
Tuesday 8 June 2010
Saikuro
ruby-lex
every keyword is interpreted into ‘state’
state used to calculateif, unless, while, until, for, elsif, when, rescue
(blocks)Recursively
Tuesday 8 June 2010
Saikuro
Good:methods < 5
Tuesday 8 June 2010
Roodi‘Ruby Object Oriented Design Inferometer’
nutmeg66 on flickr
Tuesday 8 June 2010
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
Roodi
RubyParservisitor pattern visitor: checker (Configurable) visitable: parsed nodes= extensible
Tuesday 8 June 2010
Reek
Tuesday 8 June 2010
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
Reek
OO Code smellsControl CoupleData ClumpFeature EnvyLarge ClassLong MethodLong Parameter ListSimulated PolymorphismUncommunicative Name
Tuesday 8 June 2010
Reek
RubyParserextends parsed nodes
traverses nodesreturns code after Ruby2Ruby
Tuesday 8 June 2010
rails_best_practices
kamoda on Flickr
Tuesday 8 June 2010
./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
rails_best_practices
Tuesday 8 June 2010
rails_best_practices
Visitor patternvisitor : checking_visitorvisitable: visitable sexp
Tuesday 8 June 2010
Churn
Tuesday 8 June 2010
Churn
Not only classes but also methods(RubyParser)
Version control: git, Hg, svnLocates changes in source using logs
(as in git log)
Tuesday 8 June 2010
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
Churn
common sense ... mostly useful in maintenance phase
Tuesday 8 June 2010
Rcov
Tuesday 8 June 2010
Rcov
Total coverage: comments included
Tuesday 8 June 2010
Rcov
Executes testkeeps track of the executed linesUsing C extension when possible
to hook into MRI
(experimental for 1.9)
Tuesday 8 June 2010
Rcov
good: 100% coverage
Tuesday 8 June 2010
Heckle
Tuesday 8 June 2010
Heckle
ParseTree + Ruby2Rubymutate
Tuesday 8 June 2010
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
time-consuming: combinatorialsmore for small programs (gems, scripts)
doesn’t work for ruby 1.9 (ParseTree)
Heckle
Tuesday 8 June 2010
cyclomatic complexity
size
code complexity code similarities
test coverage
antipatterns
rake stats
Flay
ReekRoodi
Flog
Saikuro
Heckle Rcov
Rails
R_B_P
Tuesday 8 June 2010
metric_fu
Tuesday 8 June 2010
what these metrics don’t tell you
Bugs
Tuesday 8 June 2010
what these metrics don’t tell you
code performanceRuby Profiling
Tuesday 8 June 2010
Reads like a book
Tuesday 8 June 2010
06:30
12 hours To Rate a Rails Application
Tuesday 8 June 2010
OrbitalJoe on flickr
check out the good stuff
Tuesday 8 June 2010
Database
db/schema.rbseed data
everything in migrations ?
Tuesday 8 June 2010
views
Bad:unindenteddivitis(too much) javascript in bodytoo much logic in viewiew
Tuesday 8 June 2010
04:30
12 hours To Rate a Rails Application
Tuesday 8 June 2010
Tests
Tuesday 8 June 2010
maintainable test suite
tests = software
changes in implementationchanges in requirements
Tuesday 8 June 2010
maintainable test suite
express code responsibilityhide implementation detail
Tuesday 8 June 2010
maintainable test suite
-> expressive code
(DRY not mandatory)
Tuesday 8 June 2010
02:30
12 hours To Rate a Rails Application
Tuesday 8 June 2010
Deployment
photo by devilarts on flickrTuesday 8 June 2010
Deployment
Tuesday 8 June 2010
Deployment
Automation, automation, automation
Tuesday 8 June 2010
Deployment
deployment = softwaresame rules apply
Tuesday 8 June 2010
Deployment
TrafficPerformance tests
Bottlenecks
Tuesday 8 June 2010
01:00
12 hours To Rate a Rails Application
Tuesday 8 June 2010
Brownie Points
Tuesday 8 June 2010
Continuous integration
... and they’re using it
Tuesday 8 June 2010
Documentation of any kind
... and it’s up to date
Tuesday 8 June 2010
monitoringexception notification
Log analyzers
Tuesday 8 June 2010
testing javascript
Continuous performance testing
Tuesday 8 June 2010
00:00
12 hours To Rate a Rails Application
Tuesday 8 June 2010
http://railroad.rubyforge.org/http://www.igvita.com/2008/12/11/ruby-ast-for-fun-and-profit/http://ruby.sadi.st/Ruby_Sadist.htmlhttp://goruco2008.confreaks.com/04_davis.htmlhttp://cwd.dhemery.com/2009/11/wmaat/http://c2.com/cgi/wiki?AbcMetrichttp://hissa.nist.gov/HHRFdata/Artifacts/ITLdoc/235/title.htmhttp://blog.rubybestpractices.com/posts/judofyr/sexp-for-rubyists.html
Elise Huard @[email protected]://jabberwocky.eu
Tuesday 8 June 2010
Top Related