Frozen rails 2012 - Fighting Code Smells
Upcoming SlideShare
Loading in...5
×
 

Frozen rails 2012 - Fighting Code Smells

on

  • 1,404 views

 

Statistics

Views

Total Views
1,404
Views on SlideShare
1,092
Embed Views
312

Actions

Likes
1
Downloads
6
Comments
0

2 Embeds 312

http://lanyrd.com 311
http://www.hanrss.com 1

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • Runtime warnings (like parens in calls, ineffective global variables)\nCode style violations (naming conventions, parentheses around conditional)\nFramework pattern violations - MVC pattern violations\n
  • Mention that\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Frozen rails 2012 - Fighting Code Smells Frozen rails 2012 - Fighting Code Smells Presentation Transcript

  • Fighting Code Smells ruby code analysis tools Dennis Ushakov
  • Pareto Principle • 20% Write new code • 80% Modify existing code
  • Does This Smell?a = something.valid?if (a.to_s == "true") # code hereend View slide
  • Does This Smell?def has_currency_rate? val = false if currency.id == company.currency.id or rate.blank? else val = true end valend View slide
  • Does This Smell?class FinancialEventObserver < ActiveRecord::Observer observe Payment, Invoice def before_save(model) event = nil if model.class == Payment if model.new_record? event = FinancialEvent.new(:event => FinancialEvent::Event::PAYMENT_INVOICE, :arguments => {:client_name => model.invoice.client.short_name, :invoice_number =>model.invoice.invoice_number}, :company_id=>model.invoice.client.company.id) end elsif model.class == Invoice i = Invoice.find_by_id model.id if model.new_record? or i.status != model.status if model.status == Invoice::Status::ESTIMATE event = FinancialEvent.new(:event => FinancialEvent::Event::ESTIMATE_SEND, :arguments => {:client_name => model.client.short_name, :invoice_number => model.invoice_number}, :company_id=>model.client.company.id) elsif model.status == Invoice::Status::APPROVED event = FinancialEvent.new(:event => FinancialEvent::Event::ESTIMATE_APPROVED, :arguments => {:client_name => model.client.short_name, :invoice_number => model.invoice_number}, :company_id=>model.client.company.id) elsif model.status == Invoice::Status::REJECTED event = FinancialEvent.new(:event => FinancialEvent::Event::ESTIMATE_REJECTED, :arguments => {:client_name => model.client.short_name, :invoice_number => model.invoice_number}, :company_id=>model.client.company.id) elsif model.status == Invoice::Status::SEND event = FinancialEvent.new(:event => FinancialEvent::Event::INVOICE_SEND, :arguments => {:client_name => model.client.short_name, :invoice_number => model.invoice_number}, :company_id=>model.client.company.id) end elsif !model.new_record? and i.state != model.state if model.state == Invoice::State::DELETED event = FinancialEvent.new(:event => FinancialEvent::Event::INVOICE_DELETED, :arguments => {:invoice_number => model.invoice_number}, :company_id=>model.client.company.id) end end end event.eventable = model.requester unless event.blank? event.save unless event.blank?
  • Code That Smells• Runtime errors• Runtime warnings• Dead code• Copy/paste• Complex method bodies• Code style violations• Framework pattern violations
  • Code Quality Tools Static Runtime flay roodi rspecmetrics_fu rcov dust simplecov heckle reek autotest pelusa cucumberflog
  • Static Tools• Inspect your code without launching it• 100% side effects free• Challenging to implement• Rails DSL magic kills ‘em
  • Reek• Class, module, method, identifier names• Using is_a?, kind_of? instead of duck typing• Code duplicates• Large classes and methods• Nested iterators
  • Flog• Uses ABC metrics system • Assignment • Branches • Conditions • |ABC| = √(A²+B²+C²)• Consider revising most painful methods
  • Flay • Analyzes code duplicates • Ignores identifier/ constants names • Consider refactoring code that’s reported
  • Roodi• Assignments in conditions• Case blocks without else• Large classes, modules and methods• Naming conventions• Cyclomatic complexity
  • metrics_fu/metricalProvides aggregate results for• Flay• Flog• Reek• Roodi
  • Runtime Tools• Inspect your code by launching it• 100% follow the way Ruby works• Cope well with DSL magic• May have side effects• Works until the very first failure
  • Runtime Tools• Code testing • Test::Unit/MiniTest • RSpec/Cucumber • Autotest/CI• Code coverage • RCov/SimpleCov • Heckle
  • Heckle• Changes code • if → unless • Calls are changed • Numbers are changed• Runs tests• At least one test should fail after change
  • RubyMine• Static analysis • On-the-fly inspections with quickfixes • Understands Rails DSLs • Code duplication• Dynamic analysis tools integration • Graphical representation • Autotest simulation • Stacktrace navigation
  • Refactorings• Rename• Extract • Method • Class/Module • Variable/Parameter
  • Morale• Use static analysis tools• Don’t forget to test• Try RubyMine http://jetbrains.com/ ruby
  • dennis.ushakov@jetbrains.com en_Dal denofevil