SlideShare une entreprise Scribd logo
1  sur  85
Télécharger pour lire hors ligne
RUBY META
PROGRAMMING.
@fnando
AVISOS.
TUDO É OBJETO.
    INCLUINDO CLASSES.
MUITO CÓDIGO.
VARIÁVEIS DE
    CLASSE.
class MyLib
  @@name = "mylib"

  def self.name
    @@name
  end
end
MyLib.name
#=> “mylib”
class MyOtherLib < MyLib
  @@name = "myotherlib"
end
MyOtherLib.name
#=> “myotherlib”

MyLib.name
#=> “myotherlib”
VARIÁVEIS DE
     CLASSE SÃO
COMPARTILHADAS.
VARIÁVEIS DE
  INSTÂNCIA.
class MyLib
  @name = "mylib"

  def self.name
    @name
  end
end
MyLib.name
#=> “mylib”
class MyOtherLib < MyLib
  @name = "myotherlib"
end
MyOtherLib.name
#=> “myotherlib”

MyLib.name
#=> “mylib”
VARIÁVEIS DE
  INSTÂNCIA
 PERTENCEM
 AO OBJETO.
METACLASSE.
class MyLib
  class << self
  end
end
class MyLib # ruby 1.9.2+
  singleton_class.class_eval do
  end
end
class Object
  def singleton_class
    class << self; self; end
  end
end unless Object.respond_to?(:singleton_class)
class MyLib
  class << self
    attr_accessor :name
  end
end
MyLib.name = "mylib"
MyLib.name
#=> mylib
BLOCOS.
MÉTODOS PODEM
RECEBER BLOCOS.
def run(&block)
end
BLOCOS PODEM
SER EXECUTADOS.
def run(&block)
  yield arg1, arg2
end
def run(&block)
  block.call(arg1, arg2)
end
def run(&block)
  block[arg1, arg2]
end
def run(&block) # ruby   1.9+
  block.(arg1, arg2)
end
METACLASSE,
   BLOCOS E
 VARIÁVEL DE
  INSTÂNCIA.
MyLib.configure do |config|
  config.name = "mylib"
end
class MyLib
  class << self
    attr_accessor :name
  end

  def self.configure(&block)
    yield self
  end
end
EVALUATION.
eval, class_eval, e
    instance_eval
MyLib.class_eval <<-RUBY
  "running inside class"
RUBY
#=> “running inside class”
MyLib.class_eval do
  "running inside class"
end
#=> “running inside class”
handler = proc {
  self.kind_of?(MyLib)
}

handler.call
#=> false
handler = proc {
  self.kind_of?(MyLib)
}

lib.instance_eval(&handler)
#=> true
BLOCOS,
METACLASSE,
VARIÁVEIS DE
  INSTÂNCIA,
 EVALUATION.
MyLib.configure do
  self.name = "mylib"
  name
  #=> “mylib”
end
class MyLib
  class << self
    attr_accessor :name
  end

  def self.configure(&block)
    instance_eval(&block)
  end
end
DEFINIÇÃO DE
   MÉTODOS.
MONKEY
PATCHING.
class Integer
  def kbytes
    self * 1024
  end
end

128.kbytes
#=> 131072
define_method.
MyLib.class_eval do
  define_method "name" do
    @name
  end

  define_method "name=" do |name|
    @name = name
  end
end
lib = MyLib.new
lib.name = "mynewname"
lib.name
#=> “mynewname”
EVALUATION.
MyLib.class_eval <<-RUBY
  def self.name
    "mylib"
  end

  def name
     "mylib's instance"
  end
RUBY
MyLib.class_eval do
  def self.name
    "mylib"
  end

  def name
    "mylib's instance"
  end
end
MyLib.name
#=> “mylib”

MyLib.new.name
#=> “mylib’s instance”
BLOCOS,
 EVALUATION,
DEFINIÇÃO DE
   MÉTODOS.
MyLib.class_eval do
  name "mylib"

  name
  #=> “mylib”
end
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 :name
end
MyLib.class_eval do
  name "mylib"

  name
  #=> “mylib”
end
configure do
  name "mylib"

  name
  #=> “mylib”
end
def configure(&block)
  MyLib.instance_eval(&block)
end
DISCLAIMER.
METHOD MISSING.
MyLib.new.invalid
NoMethodError: undefined method ‘invalid’ for
#<MyLib:0x10017e2f0>
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
  end
end
class MyLib
  #...

 def respond_to?(method, include_private = false)
   if NAMES.key?(method.to_sym)
     true
   else
     super
   end
 end
end
lib.name
#=> “mylib’s instance”



lib.respond_to?(:name)
#=> true
MIXINS.
class MyLib
  extend Accessor
  accessor :name
end

class MyOtherLib
  extend Accessor
  accessor :name
end
module Accessor
  def accessor(name)
    class_eval <<-RUBY
      def self.#{name}(*args)
         if args.size.zero?
           @#{name}
         else
           @#{name} = args.last
         end
      end
    RUBY
  end
end
MONKEY
PATCHING, MIXINS,
     EVALUATION,
        DYNAMIC
   DISPATCHING E
          HOOKS.
class Conference < ActiveRecord::Base
  has_permalink
end
"welcome to QConSP".to_permalink
#=> “welcome-to-qconsqp”
class String
  def to_permalink
    self.downcase.gsub(/[^[a-z0-9]-]/, "-")
  end
end
class Conference < ActiveRecord::Base
  before_validation :generate_permalink

  def generate_permalink
    write_attribute :permalink, name.to_s.to_permalink
  end
end
module Permalink
end

ActiveRecord::Base.send :include, Permalink
module Permalink
  def self.included(base)
    base.send :extend, ClassMethods
  end
end
module Permalink
  # ...
  module ClassMethods
    def has_permalink
      class_eval do
        before_validation :generate_permalink
        include InstanceMethods
      end
    end
  end
end
module Permalink
  # ...
 module InstanceMethods
   def generate_permalink
     write_attribute :permalink, name.to_s.to_permalink
   end
 end
end
conf = Conference.create(:name => "QConSP 2010")
conf.permalink
#=> "qconsp-2010"
ENTÃO...
META
PROGRAMMING É
  COMPLICADO.
MAS NEM TANTO.
APRENDA RUBY.
OBRIGADO.
nandovieira.com.br
simplesideias.com.br
       spesa.com.br
  github.com/fnando
            @fnando

Contenu connexe

Tendances

PHP Belfast | Collection Classes
PHP Belfast |  Collection ClassesPHP Belfast |  Collection Classes
PHP Belfast | Collection ClassesTim Swann
 
Simplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 StepsSimplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 Stepstutec
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Knowgirish82
 
Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)mpvanwinkle
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
 

Tendances (10)

jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
 
Jquery fundamentals
Jquery fundamentalsJquery fundamentals
Jquery fundamentals
 
PHP Belfast | Collection Classes
PHP Belfast |  Collection ClassesPHP Belfast |  Collection Classes
PHP Belfast | Collection Classes
 
jQuery
jQueryjQuery
jQuery
 
Simplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 StepsSimplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 Steps
 
jQuery Best Practice
jQuery Best Practice jQuery Best Practice
jQuery Best Practice
 
Strings
StringsStrings
Strings
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Know
 
Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 

Similaire à Ruby Metaprogramming

Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in RubyConFoo
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogrammingjoshbuddy
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101Nando Vieira
 
The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)lazyatom
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the BasicsMichael Koby
 
Extending Rails with Plugins (2007)
Extending Rails with Plugins (2007)Extending Rails with Plugins (2007)
Extending Rails with Plugins (2007)lazyatom
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Lightning talk
Lightning talkLightning talk
Lightning talknpalaniuk
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby MetaprogrammingThaichor Seng
 
Ruby — An introduction
Ruby — An introductionRuby — An introduction
Ruby — An introductionGonçalo Silva
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Introduction to the Ruby Object Model
Introduction to the Ruby Object ModelIntroduction to the Ruby Object Model
Introduction to the Ruby Object ModelMiki Shiran
 

Similaire à Ruby Metaprogramming (20)

Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
 
Extending Rails with Plugins (2007)
Extending Rails with Plugins (2007)Extending Rails with Plugins (2007)
Extending Rails with Plugins (2007)
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Lightning talk
Lightning talkLightning talk
Lightning talk
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Module Magic
Module MagicModule Magic
Module Magic
 
Dsl
DslDsl
Dsl
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby Metaprogramming
 
Ruby
RubyRuby
Ruby
 
Ruby — An introduction
Ruby — An introductionRuby — An introduction
Ruby — An introduction
 
Introducing Ruby
Introducing RubyIntroducing Ruby
Introducing Ruby
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Introduction to the Ruby Object Model
Introduction to the Ruby Object ModelIntroduction to the Ruby Object Model
Introduction to the Ruby Object Model
 
Why ruby
Why rubyWhy ruby
Why ruby
 

Plus de Nando Vieira

A explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoA explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoNando Vieira
 
Presentta: usando Node.js na prática
Presentta: usando Node.js na práticaPresentta: usando Node.js na prática
Presentta: usando Node.js na práticaNando Vieira
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpecNando Vieira
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9Nando Vieira
 
jQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe JavascriptjQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe JavascriptNando Vieira
 
Test-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoTest-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoNando Vieira
 

Plus de Nando Vieira (6)

A explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoA explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo preto
 
Presentta: usando Node.js na prática
Presentta: usando Node.js na práticaPresentta: usando Node.js na prática
Presentta: usando Node.js na prática
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpec
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9
 
jQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe JavascriptjQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe Javascript
 
Test-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoTest-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direito
 

Dernier

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 

Dernier (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 

Ruby Metaprogramming