Upload
cassio-marques
View
3.706
Download
0
Embed Size (px)
DESCRIPTION
Palestra feita no evento Ruby Masters Conf edição 2011.
Citation preview
Analisando Complexidade de Código Ruby
Utilizando Métricas para Encontrar Código que Fede
Cássio MarquesRubyMasters Conf 2011
Saturday, February 26, 2011
Cássio Marques
• código + comida vegan + livros + skate + música
• Taoweb
• Lime
• http://cassiomarques.wordpress.com
• @cassiomarques
Saturday, February 26, 2011
Porque analisar o código?
Saturday, February 26, 2011
http://www.flickr.com/photos/rovingi/312078231/Saturday, February 26, 2011
Como analisar o código?
Saturday, February 26, 2011
Estética
Saturday, February 26, 2011
Dificuldade de Manutenção
Saturday, February 26, 2011
Chute
Saturday, February 26, 2011
Abstrações
Saturday, February 26, 2011
Métricas
Saturday, February 26, 2011
Medir alguma propriedade específica
do código
Saturday, February 26, 2011
Objetivo: Quantificar o que antes era abstrato
Saturday, February 26, 2011
Métrica ABC
Saturday, February 26, 2011
Analisa Complexidade
Saturday, February 26, 2011
floggithub.com/seattlerb/flog
Saturday, February 26, 2011
AssignementDefinir o valor de uma variável explicitamente
Saturday, February 26, 2011
=*=/=-=
+=<<
etc...
Saturday, February 26, 2011
BranchingCriar um novo fluxo de execução
Saturday, February 26, 2011
ifelse
elsif (argh!)caseand
orrescueuntilwhile
Saturday, February 26, 2011
CallsChamadas a métodos
Saturday, February 26, 2011
(Outras implementações usam Condition)
Saturday, February 26, 2011
|ABC| = sqrt((A*A)+(B*B)+(C*C))
Saturday, February 26, 2011
Mas em Ruby temos mais do que isso!
Saturday, February 26, 2011
eval & cia(pontuação alta!!!)
define_methodeval
module_evalclass_eval
instance_eval
Saturday, February 26, 2011
blocos/yield
Saturday, February 26, 2011
instance_methodmethod_defined?
private_instance_methodprivante_class_methodpublic_instance_method
etc...
Introspecção
Saturday, February 26, 2011
Module#includedModule#extendedClass#inheritedmethod_defined
etc...
Hooks
Saturday, February 26, 2011
Ou seja...
Saturday, February 26, 2011
Ou seja...METAPROGRAMAÇÃO É COMPLEXO E DIFICULTA
A MANUTENÇÃO DO CÓDIGO
Saturday, February 26, 2011
Quando verificar isso no seu código?
Saturday, February 26, 2011
Frequentemente
Saturday, February 26, 2011
(já deixei para a fase final de um projeto e o
resultado foi traumático)
Saturday, February 26, 2011
Complexidade Ciclomática
Saturday, February 26, 2011
saikurohttp://saikuro.rubyforge.org/
Saturday, February 26, 2011
Mede o número de segmentos linearmente
independentes na execução do código
Saturday, February 26, 2011
Grafo direcionado para representar os
caminhos de execução
Saturday, February 26, 2011
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
Início
value % 2 == 0
value.times { |i| ...
puts i
while value >= 0
puts value -= 1
puts value
Fim
Saturday, February 26, 2011
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
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
Métrica procedural, mas pode ser usada em código OO no escopo
de métodos
Saturday, February 26, 2011
Duplicação de código
Saturday, February 26, 2011
flayhttp://ruby.sadi.st/Flay.html
Saturday, February 26, 2011
Pesquisa por códigos SEMELHANTES
Saturday, February 26, 2011
Resultados são bons candidatos para
refactoring
Saturday, February 26, 2011
Código que muda com muita frequência
Saturday, February 26, 2011
churngithub.com/danmayer/churn
Saturday, February 26, 2011
Código que muda muito == problemas
Saturday, February 26, 2011
Indica quantidade de alterações ao longo do
tempo
Saturday, February 26, 2011
MétodosClasses
Arquivos
Saturday, February 26, 2011
git/mercurial
Saturday, February 26, 2011
Code Smells
Saturday, February 26, 2011
Sintoma que indica algum problema mais
sério
Saturday, February 26, 2011
O código pode feder por vários motivos
Saturday, February 26, 2011
reekgithub.com/kevinrutherford/reek
Saturday, February 26, 2011
Aceita opções sobre quais smells identificar/
ignorar
Saturday, February 26, 2011
Atributos
Saturday, February 26, 2011
readers/writers (ou getters/setters) podem
expor demais seus objetos
Saturday, February 26, 2011
Variáveis de Classe
Saturday, February 26, 2011
1 class MyClass2 @@my_class_variable = 13 4 class << self5 attr_accessor :my_other_class_variable6 end7 end
Saturday, February 26, 2011
Aumenta o escopo global
Saturday, February 26, 2011
Classe Longa
Saturday, February 26, 2011
Muitas linhas
Saturday, February 26, 2011
Muitas variáveis de instância
Saturday, February 26, 2011
Muitos métodos
Saturday, February 26, 2011
*provavelmente*fazendo coisa demais!
Saturday, February 26, 2011
Método Longo
Saturday, February 26, 2011
Lista de Parâmetros Longa
Saturday, February 26, 2011
1 def pay_with_credit_card(number, security_code, holder_name, expiration, value)2 # ...3 end
Saturday, February 26, 2011
Possíveis soluções
Saturday, February 26, 2011
Passar um hash
Saturday, February 26, 2011
Encapsular em um objeto
Saturday, February 26, 2011
Baixa Coesão
Feature Envy
Saturday, February 26, 2011
1 class Cart2 def price3 @item.price + @item.tax4 end5 end
Saturday, February 26, 2011
Baixa Coesão
Utility Function
Saturday, February 26, 2011
Método que não depende do estado do
objeto
Saturday, February 26, 2011
1 class Oven2 def formatted_temperature(sensor)3 "#{sensor.temperature} #{sensor.unit}"4 end5 end
Saturday, February 26, 2011
Polimorfismo Simulado
Saturday, February 26, 2011
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
switch também :)
(o reek ainda não identifica)
Saturday, February 26, 2011
Uncommunicative Names
Saturday, February 26, 2011
Nomes não refletem a intenção do código
Saturday, February 26, 2011
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
Pode ser configurado com uma lista de regexps
default [/^.[0-9]*$/]
Saturday, February 26, 2011
Cobertura de Teste
Saturday, February 26, 2011
!= “bem testado”
Saturday, February 26, 2011
rcovhttp://eigenclass.org/hiki.rb?rcov
Saturday, February 26, 2011
Pode indicar trechos do código que foram
negligenciados
Saturday, February 26, 2011
Too Simple To Break
Saturday, February 26, 2011
Novas funcionalidades são adicionadas, mas continua sem testes
Saturday, February 26, 2011
Saturday, February 26, 2011
Saturday, February 26, 2011
Outros smellse
erros de estilo
Saturday, February 26, 2011
roodigithub.com/martinjandrews/roodi
Saturday, February 26, 2011
Atribuição de valor dentro de uma
estrutura condicional
Saturday, February 26, 2011
1 # Deveria ser foo == 1002 if foo = 1003 # ...4 end
Saturday, February 26, 2011
1 # Falso positivo...2 def some_method(value)3 if @value = value4 # ...5 end6 end
Saturday, February 26, 2011
case sem cláusula else
Saturday, February 26, 2011
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
Classes com muitas linhas de código
(por padrão limita em 300)
Saturday, February 26, 2011
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
cláusulas rescue vazias
Saturday, February 26, 2011
1 def calculate_factor(number)2 begin3 SOME_CONSTANT / number4 rescue5 6 end7 end
Saturday, February 26, 2011
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
Uso de loops com for
Saturday, February 26, 2011
1 def print_list(list)2 for value in list do3 puts value4 end5 end
Saturday, February 26, 2011
1 def print_list(list)2 list.each {|value| puts value }3 end
Saturday, February 26, 2011
Métodos com muitas linhas de código
(por padrão limita em 20)
Saturday, February 26, 2011
Padrão para nomes de métodos
(verifica se os nomes dos métodos estão snake_case)
Saturday, February 26, 2011
github.com/flyerhzm/rails_best_practices
rails_best_practices
Saturday, February 26, 2011
Ok...
Saturday, February 26, 2011
Mas é muita coisa para gerenciar!
Saturday, February 26, 2011
http://metric-fu.rubyforge.org/
metric_fu
Saturday, February 26, 2011
saikuro + flog + flay + rcov + reek + roodi + churn +
rails_best_practices
Saturday, February 26, 2011
rake metrics:all
Saturday, February 26, 2011
Integração Contínua
Saturday, February 26, 2011
Métricas ao longo do tempo
Saturday, February 26, 2011
Relatórios!
Saturday, February 26, 2011
Saturday, February 26, 2011
Saturday, February 26, 2011
Saturday, February 26, 2011
Saturday, February 26, 2011
Problema:
Saturday, February 26, 2011
O metric_fu acaba virando uma dependência
do seu projeto
Saturday, February 26, 2011
github.com/iain/metrical
metrical
Saturday, February 26, 2011
$ gem install metrical$ cd /path/of/your/project$ metrical
Saturday, February 26, 2011
Dúvidas?
Saturday, February 26, 2011
Obrigado!
Saturday, February 26, 2011