you can't miss what you can't measure
Embed Size (px)
DESCRIPTION
Adrift at sea, a GPS device will report your precise latitude and longitude, but if you don't know what those numbers mean, you're just as lost as before. Similarly, there are many tools that offer a wide variety of metrics about your code, but other than making you feel good, what are you supposed to do with this knowledge? Let's answer that question by exploring what the numbers mean, how static code analysis can add value to your development process, and how it can help us chart the unexplored seas of legacy code.TRANSCRIPT

YOU CAN’TMISS WHATYOU CAN’T MEASURE


Y’uh can’ git the’uh fruhm he’uh
[You can’t get there from here]








RED ➭ GREEN ➭ REFACTOR


1. Denial2. Anger3. Bargaining4. Depression5. Acceptance

1. Depression2. Bargaining3. Anger4. Acceptance5. Denial


@customers = Person.find_by_contents(@phrase, :columns => ['first_name', 'last_name', 'business_name', 'email_address', 'phone1'], :include => { :contacts => :customer }, :limit => 50).collect { |person| person.contacts.collect { |contact| contact.customer } }.flatten

{10:51}[1.9.3]~/project:master ✓ ➭ git blame app/controllers/customers_... ... cf2ee204 (Kerri Miller 2012-02-18 12:09:22 -0700 36)


TEST COVERAGE

TEST COVERAGEC0 — % of lines of code that have been executed
C1 — % of branches that have been followed at least once C2 — % of unique paths through the source code that have been followed


LINES OF CODE

LINES OF CODE{20:32}[1.9.3]~/project:master ✓ ➭ rake stats
+----------------------+-------+-------+---------+---------+-----+-------+| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |+----------------------+-------+-------+---------+---------+-----+-------+| Controllers | 2297 | 1566 | 18 | 106 | 5 | 12 || Helpers | 177 | 137 | 0 | 18 | 0 | 5 || Models | 3948 | 2522 | 35 | 272 | 7 | 7 || Libraries | 164 | 92 | 4 | 12 | 3 | 5 || Model specs | 2863 | 2143 | 1 | 2 | 2 | 1069 || View specs | 5 | 3 | 0 | 0 | 0 | 0 || Controller specs | 4283 | 3632 | 0 | 0 | 0 | 0 || Helper specs | 152 | 108 | 0 | 0 | 0 | 0 || Library specs | 51 | 36 | 0 | 0 | 0 | 0 |+----------------------+-------+-------+---------+---------+-----+-------+| Total | 13940 | 10239 | 58 | 410 | 7 | 22 |+----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 4317 Test LOC: 5922 Code to Test Ratio: 1:1.4

STATIC vs DYNAMIC

"Data is easy. Information is hard."
-Dr Ying Li

COMPLEXITY

CYCLOMATIC

lin·e·ar·li

ASSIGNMENTSBRANCHESCONDITIONALS

class Test def blah a = eval "1+1" # 1.2 (a=) + 6.0 (eval) if a == 2 then # 1.2 (if) + 1.2(==) + 0.4 (fixnum) puts "yay" # 1.2 (puts) end endend # 11.2 total
FLOG

• Extract Method• Decompose Objects• Rethink your domain model

CHURN

app/models/user.rb = 84
app/models/invoice.rb = 88

Wonderland Trail
Length:47.2 miles

Wonderland Trail
Length:47.2 miles

app/models/user.rb = 84
app/models/invoice.rb = 88




{10:54}[1.9.3]~/project:master ✓ ➭ git blame app/models/subscription.rb ... c9ce82b4 (Kerri Miller 2012-05-18 10:19:47 -0700

{20:32}[1.9.3]~/project:master ✓ ➭ flog -a app/models/subscription.rb 1609.9: flog total 61.9: flog/method average
408.8: Subscription#update app/models/subscription.rb:472 323.2: Subscription#new app/models/subscription.rb:250 252.0: Subscription#reply app/models/subscription.rb:137 230.5: Subscription::send_notifications app/models/subscription.rb:78 33.6: Subscription#none 25.5: Subscription#can_expire? app/models/subscription.rb:155 11.7: Subscription::reject_no_ack app/models/subscription.rb:205 4.8: Subscription#initialize app/models/subscription.rb:64 4.4: Subscription#expire! app/models/subscription.rb:183 3.7: Subscription#unexpire! app/models/subscription.rb:194 3.4: Subscription#reason_text app/models/subscription.rb:172 2.2: Subscription#is_current? app/models/subscription.rb:178 2.0: Subscription#to_s app/models/subscription.rb:71

{20:33}[1.9.3]~/project:master ✓ ➭ flog -d app/models/subscription.rb 321.7: flog total 32.2: flog/method average
230.5: Subscription::send_notifications app/models/subscription.rb:78 47.8: branch 31.7: ticket 23.1: assignment 17.9: user 17.6: [] 12.2: empty? 9.8: support_queue 8.1: deliver 8.0: class 7.6: email_address 7.0: ==

{08:16}[1.9.3]~/project:master ✓ ➭ flog -a app/models/subscription.rb
52.8: Subscription::send_notifications app/models/subscription.rb:80 28.8: Subscription#none 25.5: Subscription#can_expire? app/models/subscription.rb:119 10.2: Subscription::set_mail_options app/models/subscription.rb:221 9.8: Subscription::email_staff app/models/subscription.rb:268 8.5: Subscription::filter_subscriptions app/models/subscription.rb:17 7.9: Subscription::email_reviewers app/models/subscription.rb:258 7.3: Subscription::email_subscribers app/models/subscription.rb:169 6.3: Subscription::subscriber_emails app/models/subscription.rb:204 5.0: Subscription::log_rate_limited app/models/subscription.rb:239 4.8: Subscription#initialize app/models/subscription.rb:65 4.7: Subscription::extract_email_addresses app/models/subscription.rb 4.6: Subscription::filter_rate_limited app/models/subscription.rb:248 4.4: Subscription#expire! app/models/subscription.rb:147 4.0: Subscription::wants_notifications_on_own_posts? app/models/subsc 3.7: Subscription#unexpire! app/models/subscription.rb:158 3.4: Subscription#reason_text app/models/subscription.rb:136 3.2: Subscription::valid_recipient? app/models/subscription.rb:187 2.4: Subscription::ok_to_email? app/models/subscription.rb:183 2.2: Subscription#is_current? app/models/subscription.rb:142 2.0: Subscription#to_s app/models/subscription.rb:73 1.5: Subscription::find_reviewers app/models/subscription.rb:254 1.4: Subscription::mail_subject app/models/subscription.rb:217

{08:43}[1.9.3]~/project:master ✓ ➭ flog -a app/models/subscription.rb 27.9: Subscription#none 25.5: Subscription#can_expire? app/models/subscription.rb:78 4.8: Subscription#initialize app/models/subscription.rb:65 4.4: Subscription#expire! app/models/subscription.rb:106 3.7: Subscription#unexpire! app/models/subscription.rb:117 3.4: Subscription#reason_text app/models/subscription.rb:95 2.2: Subscription#is_current? app/models/subscription.rb:101 2.0: Subscription#to_s app/models/subscription.rb:73
{08:43}[1.9.3]~/project:master ✓ ➭ flog -a app/models/subscriber_notifier.rb 136.6: flog total 8.5: flog/method average
54.1: SubscriberNotifier::send_notifications app/models/subscriber_notif 12.0: SubscriberNotifier::email_subscribers app/models/subscriber_notifi 10.2: SubscriberNotifier::set_mail_options app/models/subscriber_notifie 9.8: SubscriberNotifier::email_staff app/models/subscriber_notifier.rb 8.5: SubscriberNotifier::filter_subscriptions app/models/subscriber_not 7.9: SubscriberNotifier::email_reviewers app/models/subscriber_notifier 6.3: SubscriberNotifier::subscriber_emails app/models/subscriber_notifi 5.0: SubscriberNotifier::log_rate_limited app/models/subscriber_notifie 4.7: SubscriberNotifier::extract_email_addresses app/models/subscriber_ 4.6: SubscriberNotifier::filter_rate_limited app/models/subscriber_noti 4.0: SubscriberNotifier::wants_notifications_on_own_posts? app/models/s 3.2: SubscriberNotifier::valid_recipient? app/models/subscriber_notifie 2.4: SubscriberNotifier::ok_to_email? app/models/subscriber_notifier.rb


> gem install flay

rails_best_practices reek roodi pelusa cane
BEST PRACTICES & STYLE



THANKS!★ @kerrizor
★ glass artist
★ vespa mechanic
★ lighting designer
★ professional poker player
★ Senior Developer @ Amazon, Contour.com, Blue Box Group