Your SlideShare is downloading. ×
  • Like
Frozen rails 2012 - Fighting Code Smells
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Frozen rails 2012 - Fighting Code Smells

  • 1,253 views
Published

 

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,253
On SlideShare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
6
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \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

Transcript

  • 1. Fighting Code Smells ruby code analysis tools Dennis Ushakov
  • 2. Pareto Principle • 20% Write new code • 80% Modify existing code
  • 3. Does This Smell?a = something.valid?if (a.to_s == "true") # code hereend
  • 4. Does This Smell?def has_currency_rate? val = false if currency.id == company.currency.id or rate.blank? else val = true end valend
  • 5. 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?
  • 6. Code That Smells• Runtime errors• Runtime warnings• Dead code• Copy/paste• Complex method bodies• Code style violations• Framework pattern violations
  • 7. Code Quality Tools Static Runtime flay roodi rspecmetrics_fu rcov dust simplecov heckle reek autotest pelusa cucumberflog
  • 8. Static Tools• Inspect your code without launching it• 100% side effects free• Challenging to implement• Rails DSL magic kills ‘em
  • 9. Reek• Class, module, method, identifier names• Using is_a?, kind_of? instead of duck typing• Code duplicates• Large classes and methods• Nested iterators
  • 10. Flog• Uses ABC metrics system • Assignment • Branches • Conditions • |ABC| = √(A²+B²+C²)• Consider revising most painful methods
  • 11. Flay • Analyzes code duplicates • Ignores identifier/ constants names • Consider refactoring code that’s reported
  • 12. Roodi• Assignments in conditions• Case blocks without else• Large classes, modules and methods• Naming conventions• Cyclomatic complexity
  • 13. metrics_fu/metricalProvides aggregate results for• Flay• Flog• Reek• Roodi
  • 14. 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
  • 15. Runtime Tools• Code testing • Test::Unit/MiniTest • RSpec/Cucumber • Autotest/CI• Code coverage • RCov/SimpleCov • Heckle
  • 16. Heckle• Changes code • if → unless • Calls are changed • Numbers are changed• Runs tests• At least one test should fail after change
  • 17. RubyMine• Static analysis • On-the-fly inspections with quickfixes • Understands Rails DSLs • Code duplication• Dynamic analysis tools integration • Graphical representation • Autotest simulation • Stacktrace navigation
  • 18. Refactorings• Rename• Extract • Method • Class/Module • Variable/Parameter
  • 19. Morale• Use static analysis tools• Don’t forget to test• Try RubyMine http://jetbrains.com/ ruby
  • 20. dennis.ushakov@jetbrains.com en_Dal denofevil