Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Metaprogramação Ruby

4,106 views

Published on

Formas de como aplicar metaprogramação com Ruby e principalmente os cuidados para quando se aplicar.

Published in: Education
  • Be the first to comment

Metaprogramação Ruby

  1. 1. METAPROGRAMAÇÃORUBYMarcos Brizeno
  2. 2. Cientista da ComputaçãoConsultor ThoughtWorksCearense!@marcosbrizenobrizeno.wordpress.com
  3. 3. Avisos
  4. 4. Conteúdo não indicadopara menores de 18 anos
  5. 5. Exemplos de código nãoforam testados
  6. 6. <jabá></jabá>
  7. 7. ü Discutir o que émetaprogramaçãoü Diferenciar reflexão emetaprogramaçãoü Como ametaprogramação podenos ajudarü Como ametaprogramação podenos atrapalharü Se divertir :D
  8. 8. ⊠ Ruby⊠ Orientação a Objetos
  9. 9. O que éMetaprogramação?WAT???
  10. 10. § Código que escreve código§ Programa que escreveprogramas§ Altera código em tempode execução§ Alterar o comportamentodo programa com oprograma§ Lógica escondidadadentro de si mesma
  11. 11. Reflexão§ Inspecionar opróprio objeto§ respond_to?§ methods§ class_variable_get/setMetaprogramação§ Programa queescreve programa§ define_method§ method_missing§ class_eval
  12. 12. O que éMetaprogramação?WAT???
  13. 13. Metaprogramação§ Código genérico§ Removeduplicações§ É muito foda =)
  14. 14. Metaprogramação§ Código difícil de ler§ Complexo§ É muito foda =(
  15. 15. Exemplo Simples:§ Ruby accessors:§ attr_accessor§ attr_reader§ attr_writer
  16. 16. class AttrExamplesattr_accessor :accessorattr_reader :readerattr_writer :writerend
  17. 17. class AttrExamplesattr_accessor :accessorattr_reader :readerattr_writer :writerendModificadores devisibiliade/acesso
  18. 18. class AttrExamplesattr_accessor :accessorattr_reader :readerattr_writer :writerendModificadores devisibiliade/acessoAttributos daclasse/instancias
  19. 19. class AttrExamplesattr_accessor :accessorattr_reader :readerattr_writer :writerendModificadores devisibiliade/acessoAttributos daclasse/instancias
  20. 20. class AttrExamplesattr_accessor :accessorattr_reader :readerattr_writer :writerendModificadores devisibiliade/acessoAttributos daclasse/instancias
  21. 21. Rails Modelsclass Product < ActiveRecord::Baseend
  22. 22. Rails Modelsclass Product < ActiveRecord::BaseendCadê osatributos?Cadê oconstrutor?
  23. 23. Métodos que definemmétodos§ Definidos na class Module
  24. 24. Exemplo: attr_accessor@attr = nildef attr()@attrenddef attr=(attr)@attr = attrend
  25. 25. Exemplo: attr_accessor@attr = nildef attr()@attrenddef attr=(attr)@attr = attrendMétodo paraler o valorMétodo paraescrever umvalor
  26. 26. Como o ruby sabe qual o nome daminha variável?Vamos pensar um pouco…
  27. 27. #define_methodsymbol é o nomedo método que vaiser criadoblock é o que essenovo método vai fazer
  28. 28. #define_methoddef create_method(name, &block)self.class.send(:define_method,name, block)end Podemos criar qualquer métodoem qualquer lugar em qualquermomento!
  29. 29. Ruby tem classes “abertas”§ Podemos adicionar ousobrescrever métodos emuma classe em qualquermomento§ Podemos adicionar ousobrescrever métodos emuma instância emqualquer momento
  30. 30. Classes ouInstâncias???
  31. 31. Nota sobre mapa do objeto
  32. 32. Classes são Objetos§ CONSTANTES são escritascom letras maiúsculas§ Uma classe é só umaConstante apontando paraum objeto do tipo Class
  33. 33. Exemplo real#showmethecode
  34. 34. Um exemplo mais “interessante”Um sistema devendas de revistasEventos:•  Nova venda•  Nova promoção•  Revista em faltaInteressados:•  Clientes (email)•  Gerentes (ActiveMQ)•  Outros apps (WS)Fontes:•  Controllers•  Workers•  Models
  35. 35. Resolvendo com programaçãoControllerModelWorkerNotifier-sell()notify_clientnotify_managernotify_app1-out_of_stock()EmailHandlerActiveMQHandlerRestHandler
  36. 36. Resolvendo com programaçãoControllerModelWorkerNotifier-sell()notify_clientnotify_managernotify_app1-out_of_stock()EmailHandlerActiveMQHandlerRestHandlerNotifier tem muitasresponsabilidadesNotifier quebramuito fácilNotifier estásobrecarregado
  37. 37. Resolvendo com programaçãoControllerModelWorkerNotifier-sell()ClientNotifier.notify_sell()ManagerNotifier.notify_sell()App1Notifier.notify_sell()-out_of_stock()EmailHandlerActiveMQHandlerRestHandlerClientNotifierManagerNotifierApp1Notifier
  38. 38. Resolvendo com programaçãoControllerModelWorkerNotifier-sell()ClientNotifier.notify_sell()ManagerNotifier.notify_sell()App1Notifier.notify_sell()-out_of_stock()EmailHandlerActiveMQHandlerRestHandlerClientNotifierManagerNotifierApp1NotifierClassesespecializadasAinda existe códigoduplicado
  39. 39. Melhorando com metaprogramaçãoControllerModelWorkerNotifierEVENTOS = [:sell, …]NOTIFIERS = [ClientNotifier, …]EmailHandlerActiveMQHandlerRestHandlerClientNotifierManagerNotifierApp1NotifierPodemos varrer a lista denotifiers e eventos para chamaras devidas notificações
  40. 40. Melhorando com metaprogramação
  41. 41. Analisando a solução§ Define váriosmétodos em tempode execução§ Código genérico§ Removeduplicações§ É muito foda =)
  42. 42. Analisando a solução§ O método nuncaser utilizado§ Código difícil de ler§ Complexo§ É muito foda =(
  43. 43. #method_missingse o ruby não sabeo que fazer ele chamao method_missing
  44. 44. Outra solução com metaprogramação
  45. 45. #method_missing§ Executado quando ummétodo não é encontrado§ Última tentativa antes delançar NoMethodError§ Só é executado apóspercorrer todo o mapa doobjeto
  46. 46. Ruby method lookupProcura noobjeto
  47. 47. Ruby method lookupProcura noobjeto Procura naclasse
  48. 48. Ruby method lookupProcura noobjeto Procura naclasseProcura nassuperclasses
  49. 49. Ruby method lookupProcura noobjeto Procura naclasseProcura nassuperclassesProcura nosmódulos
  50. 50. Ruby method lookupProcura noobjeto Procura naclasseProcura nassuperclassesProcura nosmódulosProcura naclasse daclasse
  51. 51. Analisando a solução§ Só executa quandoo método échamado§ Código genérico§ Removeduplicações§ É muito foda =)
  52. 52. Analisando a solução§ Percorre todo omapa de objetos§ Código difícil de ler§ Complexo§ É muito foda =(
  53. 53. Outra solução com metaprogramação
  54. 54. Analisando a solução§ Só executa quando ométodo é chamado§ Cria o método praevitar outra busca§ Código genérico§ Remove duplicações§ É muito foda =)
  55. 55. Analisando a solução§ Código difícil de ler§ Complexo§ É muito foda =(
  56. 56. Outra possível solução§ class_eval / instance_eval§ String -> Código“def #{event}” +“ #chama notifiers” +“end”§ PERIGO!!!
  57. 57. Aprecie com moderação§ Lógica de negócio NÃODEVE ser metaprogramada§ Muita mágica aumenta otempo de aprendizado denovos devs§ Debugar o código fica difícil§ Modificações em uma únicaparte são difíceis
  58. 58. Quais os próximos passos§ Entender Modelo de Objetos do Ruby§ Singleton class/Eigenclass§ Lambdas e Procs§ Soluções alternativas parametaprogramação
  59. 59. OBRIGADO!@marcosbrizenoGeek Night Recife

×