Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fighting Code Smells #FrozenRails

Fighting Code Smells #FrozenRails

Ruby code quality tool overview

Avatar for Dennis Ushakov

Dennis Ushakov

September 21, 2012
Tweet

More Decks by Dennis Ushakov

Other Decks in Technology

Transcript

  1. Does This Smell? def has_currency_rate?! val = false! if currency.id

    == company.currency.id or rate.blank?! else! val = true! end! val! end!
  2. 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? !
  3. Code That Smells • Runtime errors • Runtime warnings •

    Dead code • Copy/paste • Complex method bodies • Code style violations • Framework pattern violations
  4. Code Quality Tools autotest cucumber rspec simplecov rcov reek flay

    dust pelusa roodi flog metrics_fu heckle Static Runtime
  5. Static Tools • Inspect your code without launching it •

    100% side effects free • Challenging to implement • Rails DSL magic kills ‘em
  6. Reek • Class, module, method, identifier names • Using is_a?,

    kind_of? instead of duck typing • Code duplicates • Large classes and methods • Nested iterators
  7. Flog • Uses ABC metrics system • Assignment • Branches

    • Conditions • |ABC| = √(A²+B²+C²) • Consider revising most painful methods
  8. Flay • Analyzes code duplicates • Ignores identifier/ constants names

    • Consider refactoring code that’s reported
  9. Roodi • Assignments in conditions • Case blocks without else

    • Large classes, modules and methods • Naming conventions • Cyclomatic complexity
  10. 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
  11. Runtime Tools • Code testing • Test::Unit/MiniTest • RSpec/Cucumber •

    Autotest/CI • Code coverage • RCov/SimpleCov • Heckle
  12. Heckle • Changes code • if → unless • Calls

    are changed • Numbers are changed • Runs tests • At least one test should fail after change
  13. RubyMine • Static analysis • On-the-fly inspections with quickfixes •

    Understands Rails DSLs • Code duplication • Dynamic analysis tools integration • Graphical representation • Autotest simulation • Stacktrace navigation
  14. Morale • Use static analysis tools • Don’t forget to

    test • Try RubyMine
 http://jetbrains.com/ ruby