analisando complexidade de código ruby

128
Analisando Complexidade de Código Ruby Utilizando Métricas para Encontrar Código que Fede Cássio Marques RubyMasters Conf 2011 Saturday, February 26, 2011

Upload: cassio-marques

Post on 18-Dec-2014

3.706 views

Category:

Technology


0 download

DESCRIPTION

Palestra feita no evento Ruby Masters Conf edição 2011.

TRANSCRIPT

Page 1: Analisando Complexidade de Código Ruby

Analisando Complexidade de Código Ruby

Utilizando Métricas para Encontrar Código que Fede

Cássio MarquesRubyMasters Conf 2011

Saturday, February 26, 2011

Page 2: Analisando Complexidade de Código Ruby

Cássio Marques

• código + comida vegan + livros + skate + música

• Taoweb

• Lime

• http://cassiomarques.wordpress.com

• @cassiomarques

Saturday, February 26, 2011

Page 3: Analisando Complexidade de Código Ruby

Porque analisar o código?

Saturday, February 26, 2011

Page 4: Analisando Complexidade de Código Ruby

http://www.flickr.com/photos/rovingi/312078231/Saturday, February 26, 2011

Page 5: Analisando Complexidade de Código Ruby

Como analisar o código?

Saturday, February 26, 2011

Page 6: Analisando Complexidade de Código Ruby

Estética

Saturday, February 26, 2011

Page 7: Analisando Complexidade de Código Ruby

Dificuldade de Manutenção

Saturday, February 26, 2011

Page 8: Analisando Complexidade de Código Ruby

Chute

Saturday, February 26, 2011

Page 9: Analisando Complexidade de Código Ruby

Abstrações

Saturday, February 26, 2011

Page 10: Analisando Complexidade de Código Ruby

Métricas

Saturday, February 26, 2011

Page 11: Analisando Complexidade de Código Ruby

Medir alguma propriedade específica

do código

Saturday, February 26, 2011

Page 12: Analisando Complexidade de Código Ruby

Objetivo: Quantificar o que antes era abstrato

Saturday, February 26, 2011

Page 13: Analisando Complexidade de Código Ruby

Métrica ABC

Saturday, February 26, 2011

Page 14: Analisando Complexidade de Código Ruby

Analisa Complexidade

Saturday, February 26, 2011

Page 15: Analisando Complexidade de Código Ruby

floggithub.com/seattlerb/flog

Saturday, February 26, 2011

Page 16: Analisando Complexidade de Código Ruby

AssignementDefinir o valor de uma variável explicitamente

Saturday, February 26, 2011

Page 17: Analisando Complexidade de Código Ruby

=*=/=-=

+=<<

etc...

Saturday, February 26, 2011

Page 18: Analisando Complexidade de Código Ruby

BranchingCriar um novo fluxo de execução

Saturday, February 26, 2011

Page 19: Analisando Complexidade de Código Ruby

ifelse

elsif (argh!)caseand

orrescueuntilwhile

Saturday, February 26, 2011

Page 20: Analisando Complexidade de Código Ruby

CallsChamadas a métodos

Saturday, February 26, 2011

Page 21: Analisando Complexidade de Código Ruby

(Outras implementações usam Condition)

Saturday, February 26, 2011

Page 22: Analisando Complexidade de Código Ruby

|ABC| = sqrt((A*A)+(B*B)+(C*C))

Saturday, February 26, 2011

Page 23: Analisando Complexidade de Código Ruby

Mas em Ruby temos mais do que isso!

Saturday, February 26, 2011

Page 24: Analisando Complexidade de Código Ruby

eval & cia(pontuação alta!!!)

define_methodeval

module_evalclass_eval

instance_eval

Saturday, February 26, 2011

Page 25: Analisando Complexidade de Código Ruby

blocos/yield

Saturday, February 26, 2011

Page 26: Analisando Complexidade de Código Ruby

instance_methodmethod_defined?

private_instance_methodprivante_class_methodpublic_instance_method

etc...

Introspecção

Saturday, February 26, 2011

Page 27: Analisando Complexidade de Código Ruby

Module#includedModule#extendedClass#inheritedmethod_defined

etc...

Hooks

Saturday, February 26, 2011

Page 28: Analisando Complexidade de Código Ruby

Ou seja...

Saturday, February 26, 2011

Page 29: Analisando Complexidade de Código Ruby

Ou seja...METAPROGRAMAÇÃO É COMPLEXO E DIFICULTA

A MANUTENÇÃO DO CÓDIGO

Saturday, February 26, 2011

Page 30: Analisando Complexidade de Código Ruby

Quando verificar isso no seu código?

Saturday, February 26, 2011

Page 31: Analisando Complexidade de Código Ruby

Frequentemente

Saturday, February 26, 2011

Page 32: Analisando Complexidade de Código Ruby

(já deixei para a fase final de um projeto e o

resultado foi traumático)

Saturday, February 26, 2011

Page 33: Analisando Complexidade de Código Ruby

Complexidade Ciclomática

Saturday, February 26, 2011

Page 34: Analisando Complexidade de Código Ruby

saikurohttp://saikuro.rubyforge.org/

Saturday, February 26, 2011

Page 35: Analisando Complexidade de Código Ruby

Mede o número de segmentos linearmente

independentes na execução do código

Saturday, February 26, 2011

Page 36: Analisando Complexidade de Código Ruby

Grafo direcionado para representar os

caminhos de execução

Saturday, February 26, 2011

Page 37: Analisando Complexidade de Código Ruby

1 def some_method(value) 2 if value % 2 == 0 3 value.times { |i| puts i } 4 else 5 while value >= 0 6 puts value 7 value -= 1 8 end 9 end10 end

Saturday, February 26, 2011

Page 38: Analisando Complexidade de Código Ruby

Início

value % 2 == 0

value.times { |i| ...

puts i

while value >= 0

puts value -= 1

puts value

Fim

Saturday, February 26, 2011

Page 39: Analisando Complexidade de Código Ruby

C = A - V + 2PC => Complexidade ciclomática

A => Número de arestas

V => Número de vértices

P => Número de componentes conectados

Saturday, February 26, 2011

Page 40: Analisando Complexidade de Código Ruby

Pode ser utilizada para definir o número de casos de teste necessários para

ter total cobertura do código

Saturday, February 26, 2011

Page 41: Analisando Complexidade de Código Ruby

Métrica procedural, mas pode ser usada em código OO no escopo

de métodos

Saturday, February 26, 2011

Page 42: Analisando Complexidade de Código Ruby

Duplicação de código

Saturday, February 26, 2011

Page 43: Analisando Complexidade de Código Ruby

flayhttp://ruby.sadi.st/Flay.html

Saturday, February 26, 2011

Page 44: Analisando Complexidade de Código Ruby

Pesquisa por códigos SEMELHANTES

Saturday, February 26, 2011

Page 45: Analisando Complexidade de Código Ruby

Resultados são bons candidatos para

refactoring

Saturday, February 26, 2011

Page 46: Analisando Complexidade de Código Ruby

Código que muda com muita frequência

Saturday, February 26, 2011

Page 47: Analisando Complexidade de Código Ruby

churngithub.com/danmayer/churn

Saturday, February 26, 2011

Page 48: Analisando Complexidade de Código Ruby

Código que muda muito == problemas

Saturday, February 26, 2011

Page 49: Analisando Complexidade de Código Ruby

Indica quantidade de alterações ao longo do

tempo

Saturday, February 26, 2011

Page 50: Analisando Complexidade de Código Ruby

MétodosClasses

Arquivos

Saturday, February 26, 2011

Page 51: Analisando Complexidade de Código Ruby

git/mercurial

Saturday, February 26, 2011

Page 52: Analisando Complexidade de Código Ruby

Code Smells

Saturday, February 26, 2011

Page 53: Analisando Complexidade de Código Ruby

Sintoma que indica algum problema mais

sério

Saturday, February 26, 2011

Page 54: Analisando Complexidade de Código Ruby

O código pode feder por vários motivos

Saturday, February 26, 2011

Page 55: Analisando Complexidade de Código Ruby

reekgithub.com/kevinrutherford/reek

Saturday, February 26, 2011

Page 56: Analisando Complexidade de Código Ruby

Aceita opções sobre quais smells identificar/

ignorar

Saturday, February 26, 2011

Page 57: Analisando Complexidade de Código Ruby

Atributos

Saturday, February 26, 2011

Page 58: Analisando Complexidade de Código Ruby

readers/writers (ou getters/setters) podem

expor demais seus objetos

Saturday, February 26, 2011

Page 59: Analisando Complexidade de Código Ruby

Variáveis de Classe

Saturday, February 26, 2011

Page 60: Analisando Complexidade de Código Ruby

1 class MyClass2 @@my_class_variable = 13 4 class << self5 attr_accessor :my_other_class_variable6 end7 end

Saturday, February 26, 2011

Page 61: Analisando Complexidade de Código Ruby

Aumenta o escopo global

Saturday, February 26, 2011

Page 62: Analisando Complexidade de Código Ruby

Classe Longa

Saturday, February 26, 2011

Page 63: Analisando Complexidade de Código Ruby

Muitas linhas

Saturday, February 26, 2011

Page 64: Analisando Complexidade de Código Ruby

Muitas variáveis de instância

Saturday, February 26, 2011

Page 65: Analisando Complexidade de Código Ruby

Muitos métodos

Saturday, February 26, 2011

Page 66: Analisando Complexidade de Código Ruby

*provavelmente*fazendo coisa demais!

Saturday, February 26, 2011

Page 67: Analisando Complexidade de Código Ruby

Método Longo

Saturday, February 26, 2011

Page 68: Analisando Complexidade de Código Ruby

Lista de Parâmetros Longa

Saturday, February 26, 2011

Page 69: Analisando Complexidade de Código Ruby

1 def pay_with_credit_card(number, security_code, holder_name, expiration, value)2 # ...3 end

Saturday, February 26, 2011

Page 70: Analisando Complexidade de Código Ruby

Possíveis soluções

Saturday, February 26, 2011

Page 71: Analisando Complexidade de Código Ruby

Passar um hash

Saturday, February 26, 2011

Page 72: Analisando Complexidade de Código Ruby

Encapsular em um objeto

Saturday, February 26, 2011

Page 73: Analisando Complexidade de Código Ruby

Baixa Coesão

Feature Envy

Saturday, February 26, 2011

Page 74: Analisando Complexidade de Código Ruby

1 class Cart2 def price3 @item.price + @item.tax4 end5 end

Saturday, February 26, 2011

Page 75: Analisando Complexidade de Código Ruby

Baixa Coesão

Utility Function

Saturday, February 26, 2011

Page 76: Analisando Complexidade de Código Ruby

Método que não depende do estado do

objeto

Saturday, February 26, 2011

Page 77: Analisando Complexidade de Código Ruby

1 class Oven2 def formatted_temperature(sensor)3 "#{sensor.temperature} #{sensor.unit}"4 end5 end

Saturday, February 26, 2011

Page 78: Analisando Complexidade de Código Ruby

Polimorfismo Simulado

Saturday, February 26, 2011

Page 79: Analisando Complexidade de Código Ruby

1 def some_method(value) 2 if value > 10 3 if value < 20 4 if value != 15 5 puts "duh" 6 else 7 puts "meh" 8 end 9 end10 end11 end

Saturday, February 26, 2011

Page 80: Analisando Complexidade de Código Ruby

switch também :)

(o reek ainda não identifica)

Saturday, February 26, 2011

Page 81: Analisando Complexidade de Código Ruby

Uncommunicative Names

Saturday, February 26, 2011

Page 82: Analisando Complexidade de Código Ruby

Nomes não refletem a intenção do código

Saturday, February 26, 2011

Page 83: Analisando Complexidade de Código Ruby

1 class SomeClass 2 def some_method 3 # ... 4 end 5 6 def some_method_2 7 # ... 8 end 9 10 def another_method11 a = 1012 aLocalVariable = 2513 end14 end

Saturday, February 26, 2011

Page 84: Analisando Complexidade de Código Ruby

Pode ser configurado com uma lista de regexps

default [/^.[0-9]*$/]

Saturday, February 26, 2011

Page 85: Analisando Complexidade de Código Ruby

Cobertura de Teste

Saturday, February 26, 2011

Page 86: Analisando Complexidade de Código Ruby

!= “bem testado”

Saturday, February 26, 2011

Page 87: Analisando Complexidade de Código Ruby

rcovhttp://eigenclass.org/hiki.rb?rcov

Saturday, February 26, 2011

Page 88: Analisando Complexidade de Código Ruby

Pode indicar trechos do código que foram

negligenciados

Saturday, February 26, 2011

Page 89: Analisando Complexidade de Código Ruby

Too Simple To Break

Saturday, February 26, 2011

Page 90: Analisando Complexidade de Código Ruby

Novas funcionalidades são adicionadas, mas continua sem testes

Saturday, February 26, 2011

Page 91: Analisando Complexidade de Código Ruby

Saturday, February 26, 2011

Page 92: Analisando Complexidade de Código Ruby

Saturday, February 26, 2011

Page 93: Analisando Complexidade de Código Ruby

Outros smellse

erros de estilo

Saturday, February 26, 2011

Page 94: Analisando Complexidade de Código Ruby

roodigithub.com/martinjandrews/roodi

Saturday, February 26, 2011

Page 95: Analisando Complexidade de Código Ruby

Atribuição de valor dentro de uma

estrutura condicional

Saturday, February 26, 2011

Page 96: Analisando Complexidade de Código Ruby

1 # Deveria ser foo == 1002 if foo = 1003 # ...4 end

Saturday, February 26, 2011

Page 97: Analisando Complexidade de Código Ruby

1 # Falso positivo...2 def some_method(value)3 if @value = value4 # ...5 end6 end

Saturday, February 26, 2011

Page 98: Analisando Complexidade de Código Ruby

case sem cláusula else

Saturday, February 26, 2011

Page 99: Analisando Complexidade de Código Ruby

1 def some_method(value)2 case value3 when 1..104 puts "Entre 1 e 10"5 when 11..206 puts "Entre 11 e 20"7 end8 end

Saturday, February 26, 2011

Page 100: Analisando Complexidade de Código Ruby

Classes com muitas linhas de código

(por padrão limita em 300)

Saturday, February 26, 2011

Page 101: Analisando Complexidade de Código Ruby

Padrão para nome de classes e módulos

(verifica se o nome das classes e módulos está em CamelCase)

Saturday, February 26, 2011

Page 102: Analisando Complexidade de Código Ruby

cláusulas rescue vazias

Saturday, February 26, 2011

Page 103: Analisando Complexidade de Código Ruby

1 def calculate_factor(number)2 begin3 SOME_CONSTANT / number4 rescue5 6 end7 end

Saturday, February 26, 2011

Page 104: Analisando Complexidade de Código Ruby

1 def calculate_factor(number)2 begin3 SOME_CONSTANT / number4 rescue => e5 # Tratar a exceção de alguma forma...6 end7 end

Saturday, February 26, 2011

Page 105: Analisando Complexidade de Código Ruby

Uso de loops com for

Saturday, February 26, 2011

Page 106: Analisando Complexidade de Código Ruby

1 def print_list(list)2 for value in list do3 puts value4 end5 end

Saturday, February 26, 2011

Page 107: Analisando Complexidade de Código Ruby

1 def print_list(list)2 list.each {|value| puts value }3 end

Saturday, February 26, 2011

Page 108: Analisando Complexidade de Código Ruby

Métodos com muitas linhas de código

(por padrão limita em 20)

Saturday, February 26, 2011

Page 109: Analisando Complexidade de Código Ruby

Padrão para nomes de métodos

(verifica se os nomes dos métodos estão snake_case)

Saturday, February 26, 2011

Page 110: Analisando Complexidade de Código Ruby

github.com/flyerhzm/rails_best_practices

rails_best_practices

Saturday, February 26, 2011

Page 111: Analisando Complexidade de Código Ruby

Ok...

Saturday, February 26, 2011

Page 112: Analisando Complexidade de Código Ruby

Mas é muita coisa para gerenciar!

Saturday, February 26, 2011

Page 113: Analisando Complexidade de Código Ruby

http://metric-fu.rubyforge.org/

metric_fu

Saturday, February 26, 2011

Page 114: Analisando Complexidade de Código Ruby

saikuro + flog + flay + rcov + reek + roodi + churn +

rails_best_practices

Saturday, February 26, 2011

Page 115: Analisando Complexidade de Código Ruby

rake metrics:all

Saturday, February 26, 2011

Page 116: Analisando Complexidade de Código Ruby

Integração Contínua

Saturday, February 26, 2011

Page 117: Analisando Complexidade de Código Ruby

Métricas ao longo do tempo

Saturday, February 26, 2011

Page 118: Analisando Complexidade de Código Ruby

Relatórios!

Saturday, February 26, 2011

Page 119: Analisando Complexidade de Código Ruby

Saturday, February 26, 2011

Page 120: Analisando Complexidade de Código Ruby

Saturday, February 26, 2011

Page 121: Analisando Complexidade de Código Ruby

Saturday, February 26, 2011

Page 122: Analisando Complexidade de Código Ruby

Saturday, February 26, 2011

Page 123: Analisando Complexidade de Código Ruby

Problema:

Saturday, February 26, 2011

Page 124: Analisando Complexidade de Código Ruby

O metric_fu acaba virando uma dependência

do seu projeto

Saturday, February 26, 2011

Page 125: Analisando Complexidade de Código Ruby

github.com/iain/metrical

metrical

Saturday, February 26, 2011

Page 126: Analisando Complexidade de Código Ruby

$ gem install metrical$ cd /path/of/your/project$ metrical

Saturday, February 26, 2011

Page 127: Analisando Complexidade de Código Ruby

Dúvidas?

Saturday, February 26, 2011

Page 128: Analisando Complexidade de Código Ruby

Obrigado!

Saturday, February 26, 2011