Your SlideShare is downloading. ×
0
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Metaprogramming 101
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Metaprogramming 101

2,864

Published on

Published in: Technology, Sports
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,864
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
68
Comments
0
Likes
5
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

Transcript

  • 1. Metaprogramming 101Nando Vieira
  • 2. codeplane.com.br
  • 3. ode.c om.brhow toc
  • 4. O que veremosobject model, method dispatching,evaluation, hooks, DSLs.
  • 5. selfsempre será o receiver padrão.
  • 6. person.name!"#"$%"!
  • 7. class User attr_accessor :first_name, :last_name def fullname "#{first_name} #{last_name}" endend
  • 8. class User attr_accessor :first_name, :last_name def initialize(options = {}) options.each do |name, value| send("#{name}=", value) end endendUser.new({ :first_name => "John", :last_name => "Doe"})
  • 9. selfarmazena as variáveis de instância.
  • 10. class User attr_accessor :first_name, :last_nameenduser = User.newuser.first_name = "John"user.last_name = "Doe"user.instance_variables#=> ["@last_name", "@first_name"]
  • 11. variáveis de instânciaisso se aplica a todos os objetos.
  • 12. class Config @directory = "/some/directory" @environment = :productionendConfig.instance_variables#=> ["@environment", "@directory"]
  • 13. singleton_classmetaclasse, eigenclass, ghostclass.
  • 14. class Config class << self endend
  • 15. RUBY 1.9class Config singleton_class.class do # your code here endend
  • 16. RUBY 1.8class Object unless Object.respond_to?(:singleton_class) def singleton_class class << self; self; end end endend
  • 17. class Config def self.root_dir @root_dir end def self.root_dir=(dir) @root_dir = dir endend
  • 18. class Config class << self attr_accessor :root_dir endend
  • 19. estendendo o selfadicionando novos métodos.
  • 20. person = Object.newdef person.name "John Doe"endperson.name#=> "John Doe"
  • 21. person.singleton_methods#=> ["name"]
  • 22. estendendo o selfadicionando novos métodos em classes.
  • 23. class Config def Config.root_dir "/some/path" endendConfig.root_dir#=> "/some/path"
  • 24. Config.singleton_methods#=> ["root_dir"]
  • 25. class Config puts self == Configend#=> true
  • 26. class Config def Config.root_dir "/some/path" endendConfig.root_dir#=> "/some/path"
  • 27. métodos de classeeles não existem no Ruby.
  • 28. métodoslookup + dispatching.
  • 29. method lookupup and right.
  • 30. BasicObject class << BasicObject Object class << Object Module class << Module Class class << Class Person class << Person person class << person person.name
  • 31. NoMethodError
  • 32. method dispatchingexecução de métodos.
  • 33. person.name
  • 34. person.send :name
  • 35. person.send :say, "hello"
  • 36. person.__send__ :name
  • 37. person.public_send :name
  • 38. class Person attr_accessor :name, :age, :email def initialize(options = {}) options.each do |name, value| send("#{name}=", value) "#{name}=" end endend
  • 39. evaluationclass_eval, instance_eval,instance_exec, eval.
  • 40. class_evala.k.a. module_eval.
  • 41. class Person; endPerson.class_eval do puts self == Personend#=> true
  • 42. class Person; endPerson.class_eval <<-RUBY puts self == PersonRUBY#=> true
  • 43. class Person; endPerson.class_eval do def self.some_class_method end def some_instance_method endend
  • 44. class Person; endmodule Helpers # some code hereendPerson.class_eval do include Helpersend
  • 45. class Person class_eval <<-RUBY, __FILE__, __LINE__ def some_method # some code end RUBYend
  • 46. class Person class_eval <<-RUBY, __FILE__, __LINE__ def some_method raise "ffffuuuuuuuuuu" end RUBYendbegin Person.new.some_methodrescue Exception => error error.backtrace # ["person.rb:3:in `some_method", "person.rb:10"]end
  • 47. instance_evala.k.a. class_eval para instâncias.
  • 48. Person = Class.newperson = Person.newPerson.respond_to?(:class_eval) #=> truePerson.respond_to?(:instance_eval) #=> trueperson.respond_to?(:class_eval) #=> falseperson.respond_to?(:instance_eval) #=> true
  • 49. instance_execa.k.a. instance_eval on redbull.
  • 50. require "ostruct"john = OpenStruct.new(:name => "John Doe")block = proc do |time = nil| puts name puts timeendjohn.instance_eval(&block)#=> John Doe#=> #<OpenStruct name="John Doe">john.instance_exec(Time.now, &block)#=> John Doe#=> 2011-07-08 11:44:01 -0300
  • 51. evalevaluation com contexto configurável.
  • 52. def get_binding name = "John Doe" bindingendeval("defined?(name)")#=> nileval("defined?(name)", get_binding)#=> "local-variable"eval("name", get_binding)#=> "John Doe"
  • 53. hooksinterceptando eventos do Ruby.
  • 54. módulos & classesincluded, const_missing, extended,inherited, initialize_clone,initialize_copy, initialize_dup.
  • 55. includedexecutado toda vez que um módulo éincluído.
  • 56. module Ffffffuuu def self.included(base) base.class_eval do include InstanceMethods extend ClassMethods end end module InstanceMethods # some instance methods end module ClassMethods # some class methods endend
  • 57. class Person include FfffffuuuendPerson.singleton_class.included_modules#=> [Ffffffuuu::ClassMethods, Kernel]Person.included_modules#=> [Ffffffuuu::InstanceMethods, Ffffffuuu, Kernel]
  • 58. métodosmethod_added, method_missing,method_removed, method_undefined,singleton_method_added,singleton_method_removed,singleton_method_undefined
  • 59. method_missingexecutado toda vez que um método nãofor encontrado.
  • 60. class Logger attr_accessor :output LEVELS = [ :debug, :info, :warn, :error, :critical ] def initialize(output) @output = output end def log(level, message) output << "[#{level}] #{message}n" endend
  • 61. logger = Logger.new(STDOUT)logger.log :debug, "Fffffuuuuu"
  • 62. class Logger attr_accessor :output LEVELS = [ :debug, :info, :warn, :error, :critical ] def initialize(output) @output = output end def log(level, message) output << "[#{level}] #{message}n" end def method_missing(name, *args, &block) return send(:log, name, args.first) if LEVELS.include?(name) super endend
  • 63. def respond_to?(method, include_private = false) return true if LEVELS.include?(method.to_sym) superend
  • 64. DSLsfuckyeah.
  • 65. interfaces fluenteschaining.
  • 66. @message = Message.new@message.to("john").from("mary").text("bring milk.")@message.deliver#=> "mary said: john, bring milk."
  • 67. class Message def to(name) @to = name self end def from(name) @from = name self end def text(message) @text = message self endend
  • 68. module FluentAttribute def fluent_attr(*names) names.each do |name| class_eval <<-RUBY, __FILE__, __LINE__ def #{name}(value) # def to(value) @#{name} = value # @to = value self # self end # end RUBY end endend
  • 69. class Message extend FluentAttribute fluent_attr :from, :to, :textend
  • 70. dúvidas?
  • 71. obrigadohttp://nandovieira.com.br.

×