ruby metaprogramming
TRANSCRIPT
![Page 1: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/1.jpg)
RUBY METAPROGRAMMING.
![Page 2: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/2.jpg)
@fnando
![Page 3: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/3.jpg)
AVISOS.
![Page 4: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/4.jpg)
TUDO É OBJETO.INCLUINDO CLASSES.
![Page 5: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/5.jpg)
MUITO CÓDIGO.
![Page 6: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/6.jpg)
VARIÁVEIS DE CLASSE.
![Page 7: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/7.jpg)
class MyLib @@name = "mylib" def self.name @@name endend
![Page 8: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/8.jpg)
MyLib.name#=> “mylib”
![Page 9: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/9.jpg)
class MyOtherLib < MyLib @@name = "myotherlib"end
![Page 10: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/10.jpg)
MyOtherLib.name#=> “myotherlib”
MyLib.name#=> “myotherlib”
![Page 11: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/11.jpg)
VARIÁVEIS DE CLASSE SÃO
COMPARTILHADAS.
![Page 12: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/12.jpg)
VARIÁVEIS DE INSTÂNCIA.
![Page 13: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/13.jpg)
class MyLib @name = "mylib" def self.name @name endend
![Page 14: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/14.jpg)
MyLib.name#=> “mylib”
![Page 15: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/15.jpg)
class MyOtherLib < MyLib @name = "myotherlib"end
![Page 16: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/16.jpg)
MyOtherLib.name#=> “myotherlib”
MyLib.name#=> “mylib”
![Page 17: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/17.jpg)
VARIÁVEIS DE INSTÂNCIA
PERTENCEMAO OBJETO.
![Page 18: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/18.jpg)
METACLASSE.
![Page 19: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/19.jpg)
class MyLib class << self endend
![Page 20: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/20.jpg)
class MyLib # ruby 1.9.2+ singleton_class.class_eval do endend
![Page 21: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/21.jpg)
class Object def singleton_class class << self; self; end endend unless Object.respond_to?(:singleton_class)
![Page 22: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/22.jpg)
class MyLib class << self attr_accessor :name endend
![Page 23: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/23.jpg)
MyLib.name = "mylib"MyLib.name#=> mylib
![Page 24: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/24.jpg)
BLOCOS.
![Page 25: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/25.jpg)
MÉTODOS PODEM RECEBER BLOCOS.
![Page 26: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/26.jpg)
def run(&block)end
![Page 27: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/27.jpg)
BLOCOS PODEMSER EXECUTADOS.
![Page 28: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/28.jpg)
def run(&block) yield arg1, arg2end
![Page 29: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/29.jpg)
def run(&block) block.call(arg1, arg2)end
![Page 30: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/30.jpg)
def run(&block) block[arg1, arg2]end
![Page 31: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/31.jpg)
def run(&block) block.(arg1, arg2)end
# ruby 1.9+
![Page 32: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/32.jpg)
METACLASSE, BLOCOS E
VARIÁVEL DE INSTÂNCIA.
![Page 33: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/33.jpg)
MyLib.configure do |config| config.name = "mylib"end
![Page 34: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/34.jpg)
class MyLib class << self attr_accessor :name end def self.configure(&block) yield self endend
![Page 35: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/35.jpg)
EVALUATION.
![Page 36: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/36.jpg)
eval, class_eval, e instance_eval
![Page 37: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/37.jpg)
MyLib.class_eval <<-RUBY "running inside class"RUBY#=> “running inside class”
![Page 38: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/38.jpg)
MyLib.class_eval do "running inside class"end#=> “running inside class”
![Page 39: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/39.jpg)
handler = proc { self.kind_of?(MyLib)}
handler.call#=> false
![Page 40: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/40.jpg)
handler = proc { self.kind_of?(MyLib)}
lib.instance_eval(&handler)#=> true
![Page 41: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/41.jpg)
BLOCOS, METACLASSE, VARIÁVEIS DE
INSTÂNCIA, EVALUATION.
![Page 42: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/42.jpg)
MyLib.configure do self.name = "mylib" name #=> “mylib”end
![Page 43: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/43.jpg)
class MyLib class << self attr_accessor :name end def self.configure(&block) instance_eval(&block) endend
![Page 44: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/44.jpg)
DEFINIÇÃO DE MÉTODOS.
![Page 45: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/45.jpg)
MONKEY PATCHING.
![Page 46: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/46.jpg)
class Integer def kbytes self * 1024 endend
128.kbytes#=> 131072
![Page 47: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/47.jpg)
define_method.
![Page 48: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/48.jpg)
MyLib.class_eval do define_method "name" do @name end
define_method "name=" do |name| @name = name endend
![Page 49: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/49.jpg)
lib = MyLib.newlib.name = "mynewname"lib.name#=> “mynewname”
![Page 50: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/50.jpg)
EVALUATION.
![Page 51: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/51.jpg)
MyLib.class_eval <<-RUBY def self.name "mylib" end
def name "mylib's instance" endRUBY
![Page 52: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/52.jpg)
MyLib.class_eval do def self.name "mylib" end def name "mylib's instance" endend
![Page 53: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/53.jpg)
MyLib.name#=> “mylib”
MyLib.new.name#=> “mylib’s instance”
![Page 54: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/54.jpg)
BLOCOS, EVALUATION,
DEFINIÇÃO DE MÉTODOS.
![Page 55: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/55.jpg)
MyLib.class_eval do name "mylib" name #=> “mylib”end
![Page 56: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/56.jpg)
class MyLib def self.accessor(method) class_eval <<-RUBY def self.#{method}(*args) if args.size.zero? @#{method} else @#{method} = args.last end end RUBY end accessor :nameend
![Page 57: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/57.jpg)
MyLib.class_eval do name "mylib" name #=> “mylib”end
![Page 58: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/58.jpg)
configure do name "mylib"
name #=> “mylib”end
![Page 59: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/59.jpg)
def configure(&block) MyLib.instance_eval(&block)end
![Page 60: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/60.jpg)
DISCLAIMER.
![Page 61: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/61.jpg)
METHOD MISSING.
![Page 62: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/62.jpg)
MyLib.new.invalid
![Page 63: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/63.jpg)
NoMethodError: undefined method ‘invalid’ for #<MyLib:0x10017e2f0>
![Page 64: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/64.jpg)
class MyLib NAMES = { :name => "mylib’s instance" }
def method_missing(method, *args) if NAMES.key?(method.to_sym) NAMES[method.to_sym] else super end endend
![Page 65: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/65.jpg)
class MyLib #...
def respond_to?(method, include_private = false) if NAMES.key?(method.to_sym) true else super end endend
![Page 66: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/66.jpg)
lib.name#=> “mylib’s instance”
lib.respond_to?(:name)#=> true
![Page 67: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/67.jpg)
MIXINS.
![Page 68: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/68.jpg)
class MyLib extend Accessor accessor :nameend
class MyOtherLib extend Accessor accessor :nameend
![Page 69: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/69.jpg)
module Accessor def accessor(name) class_eval <<-RUBY def self.#{name}(*args) if args.size.zero? @#{name} else @#{name} = args.last end end RUBY endend
![Page 70: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/70.jpg)
MONKEY PATCHING, MIXINS,
EVALUATION, DYNAMIC
DISPATCHING E HOOKS.
![Page 71: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/71.jpg)
class Conference < ActiveRecord::Base has_permalinkend
![Page 72: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/72.jpg)
"welcome to QConSP".to_permalink#=> “welcome-to-qconsqp”
![Page 73: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/73.jpg)
class String def to_permalink self.downcase.gsub(/[^[a-z0-9]-]/, "-") endend
![Page 74: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/74.jpg)
class Conference < ActiveRecord::Base before_validation :generate_permalink
def generate_permalink write_attribute :permalink, name.to_s.to_permalink endend
![Page 75: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/75.jpg)
module Permalinkend
ActiveRecord::Base.send :include, Permalink
![Page 76: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/76.jpg)
module Permalink def self.included(base) base.send :extend, ClassMethods endend
![Page 77: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/77.jpg)
module Permalink # ... module ClassMethods def has_permalink class_eval do before_validation :generate_permalink include InstanceMethods end end endend
![Page 78: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/78.jpg)
module Permalink # ... module InstanceMethods def generate_permalink write_attribute :permalink, name.to_s.to_permalink end endend
![Page 79: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/79.jpg)
conf = Conference.create(:name => "QConSP 2010")conf.permalink#=> "qconsp-2010"
![Page 80: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/80.jpg)
ENTÃO...
![Page 81: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/81.jpg)
METAPROGRAMMING É
COMPLICADO.
![Page 82: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/82.jpg)
MAS NEM TANTO.
![Page 83: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/83.jpg)
APRENDA RUBY.
![Page 84: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/84.jpg)
OBRIGADO.
![Page 85: Ruby Metaprogramming](https://reader036.vdocuments.site/reader036/viewer/2022081505/554f4c29b4c905b9508b498f/html5/thumbnails/85.jpg)
nandovieira.com.brsimplesideias.com.br
spesa.com.brgithub.com/fnando
@fnando