SlideShare ist ein Scribd-Unternehmen logo
1 von 20
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 here
end
Does This Smell?

def has_currency_rate?
  val = false
  if currency.id == company.currency.id or rate.blank?
  else
    val = true
  end
  val
end
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                     rspec
metrics_fu                      rcov
                 dust                        simplecov
      heckle            reek   autotest
             pelusa                       cucumber
flog
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/metrical

Provides 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

Weitere ähnliche Inhalte

Was ist angesagt?

Ruby onrails cucumber-rspec-capybara
Ruby onrails cucumber-rspec-capybaraRuby onrails cucumber-rspec-capybara
Ruby onrails cucumber-rspec-capybara
Bindesh Vijayan
 
How to start using Scala
How to start using ScalaHow to start using Scala
How to start using Scala
Ngoc Dao
 

Was ist angesagt? (20)

Spring I/O 2012: Natural Templating in Spring MVC with Thymeleaf
Spring I/O 2012: Natural Templating in Spring MVC with ThymeleafSpring I/O 2012: Natural Templating in Spring MVC with Thymeleaf
Spring I/O 2012: Natural Templating in Spring MVC with Thymeleaf
 
Ruby onrails cucumber-rspec-capybara
Ruby onrails cucumber-rspec-capybaraRuby onrails cucumber-rspec-capybara
Ruby onrails cucumber-rspec-capybara
 
Gtg12
Gtg12Gtg12
Gtg12
 
Shootout! Template engines for the JVM
Shootout! Template engines for the JVMShootout! Template engines for the JVM
Shootout! Template engines for the JVM
 
Model with actors and implement with Akka
Model with actors and implement with AkkaModel with actors and implement with Akka
Model with actors and implement with Akka
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on Rails
 
Web development basics (Part-6)
Web development basics (Part-6)Web development basics (Part-6)
Web development basics (Part-6)
 
RoR (Ruby on Rails)
RoR (Ruby on Rails)RoR (Ruby on Rails)
RoR (Ruby on Rails)
 
How to start using Scala
How to start using ScalaHow to start using Scala
How to start using Scala
 
Web development basics (Part-2)
Web development basics (Part-2)Web development basics (Part-2)
Web development basics (Part-2)
 
Ruby On Rails Presentation
Ruby On Rails PresentationRuby On Rails Presentation
Ruby On Rails Presentation
 
Day 1 - Intro to Ruby
Day 1 - Intro to RubyDay 1 - Intro to Ruby
Day 1 - Intro to Ruby
 
遇見 Ruby on Rails
遇見 Ruby on Rails遇見 Ruby on Rails
遇見 Ruby on Rails
 
Thymeleaf, will it blend?
Thymeleaf, will it blend?Thymeleaf, will it blend?
Thymeleaf, will it blend?
 
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 TaiwanAutomating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
 
Back to the future: Isomorphic javascript applications
Back to the future:  Isomorphic javascript applicationsBack to the future:  Isomorphic javascript applications
Back to the future: Isomorphic javascript applications
 
Merb
MerbMerb
Merb
 
GraphQL-PHP: Dos and don'ts
GraphQL-PHP: Dos and don'tsGraphQL-PHP: Dos and don'ts
GraphQL-PHP: Dos and don'ts
 
Ruby performance - The low hanging fruit
Ruby performance - The low hanging fruitRuby performance - The low hanging fruit
Ruby performance - The low hanging fruit
 
Rango
RangoRango
Rango
 

Ähnlich wie Frozen rails 2012 - Fighting Code Smells

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
Kerry Buckley
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Code
erikmsp
 
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Yasuko Ohba
 

Ähnlich wie Frozen rails 2012 - Fighting Code Smells (20)

Rails antipattern-public
Rails antipattern-publicRails antipattern-public
Rails antipattern-public
 
Rails antipatterns
Rails antipatternsRails antipatterns
Rails antipatterns
 
Random Ruby Tips - Ruby Meetup 27 Jun 2018
Random Ruby Tips - Ruby Meetup 27 Jun 2018Random Ruby Tips - Ruby Meetup 27 Jun 2018
Random Ruby Tips - Ruby Meetup 27 Jun 2018
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
 
Developer testing 101: Become a Testing Fanatic
Developer testing 101: Become a Testing FanaticDeveloper testing 101: Become a Testing Fanatic
Developer testing 101: Become a Testing Fanatic
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best Practices
 
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
 
Testing
TestingTesting
Testing
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Code
 
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
 
Refactoring
RefactoringRefactoring
Refactoring
 
Continuous Integration For Rails Project
Continuous Integration For Rails ProjectContinuous Integration For Rails Project
Continuous Integration For Rails Project
 
Refactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and PatternsRefactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and Patterns
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
 
How to practice TDD without shooting yourself in the foot
How to practice TDD without shooting yourself in the footHow to practice TDD without shooting yourself in the foot
How to practice TDD without shooting yourself in the foot
 
Where Does the Fat Goes? Utilizando Form Objects Para Simplificar seu Código
Where Does the Fat Goes? Utilizando Form Objects Para Simplificar seu CódigoWhere Does the Fat Goes? Utilizando Form Objects Para Simplificar seu Código
Where Does the Fat Goes? Utilizando Form Objects Para Simplificar seu Código
 
Into The Box 2018 - CBT
Into The Box 2018 - CBTInto The Box 2018 - CBT
Into The Box 2018 - CBT
 
DDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCDDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVC
 
PVS-Studio and static code analysis technique
PVS-Studio and static code analysis techniquePVS-Studio and static code analysis technique
PVS-Studio and static code analysis technique
 

Kürzlich hochgeladen

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Kürzlich hochgeladen (20)

Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 

Frozen rails 2012 - Fighting Code Smells

  • 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 here end
  • 4. Does This Smell? def has_currency_rate? val = false if currency.id == company.currency.id or rate.blank? else val = true end val end
  • 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 rspec metrics_fu rcov dust simplecov heckle reek autotest pelusa cucumber flog
  • 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/metrical Provides 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

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. Runtime warnings (like parens in calls, ineffective global variables)\nCode style violations (naming conventions, parentheses around conditional)\nFramework pattern violations - MVC pattern violations\n
  7. Mention that\n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n