SlideShare uma empresa Scribd logo
1 de 48
Elegant APIs
Why your methods
should never
go missing
Presented by Andrew Timberlake
Elegant APIs


variable arguments
method_missing
blocks
instance_eval
Elegant APIs


variable arguments
method_missing
blocks
instance_eval
variable arguments   Elegant APIs




   method_missing
   blocks
   instance_eval
variable arguments   Elegant APIs

def method(arg1)
  #...
end
variable arguments   Elegant APIs

def method(arg1 = 1)
  #...
end
variable arguments            Elegant APIs

def method(arg1 = 1, arg2 = 2)
  #...
end
variable arguments                  Elegant APIs

def method(opts = {})
  options = {:arg1 => 1,
             :arg2 => 2}.merge(opts)
  #...
end
variable arguments                  Elegant APIs

def method(opts = {})
  options = {:arg1 => 1,
             :arg2 => 2}.merge(opts)
  #...
end


method :arg2 => 3
variable arguments                     Elegant APIs

#Active Record
User.create(:first_name => 'Andrew',
            :last_name => 'Timberlake')
Elegant APIs


variable arguments
method_missing
blocks
instance_eval
method_missing     Elegant APIs


   variable arguments


   blocks
   instance_eval
method_missing                            Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

puts body['background']       #=> background:#FFF




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

puts body['background']       #=> background:#FFF
puts body[:background]        #=> background:#FFF




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

puts body['background']       #=> background:#FFF
puts body[:background]        #=> background:#FFF
puts body['background-color'] #=> #FFF




                                  http://github.com/andrewtimberlake/css
method_missing                                  Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

puts   body['background']         #=>   background:#FFF
puts   body[:background]          #=>   background:#FFF
puts   body['background-color']   #=>   #FFF
puts   body.background            #=>   background:#FFF




                                        http://github.com/andrewtimberlake/css
method_missing                                  Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

puts   body['background']         #=>   background:#FFF
puts   body[:background]          #=>   background:#FFF
puts   body['background-color']   #=>   #FFF
puts   body.background            #=>   background:#FFF
puts   body.background_color      #=>   #FFF




                                        http://github.com/andrewtimberlake/css
method_missing                                  Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

puts   body['background']         #=>   background:#FFF
puts   body[:background]          #=>   background:#FFF
puts   body['background-color']   #=>   #FFF
puts   body.background            #=>   background:#FFF
puts   body.background_color      #=>   #FFF
puts   body.backgroundColor       #=>   #FFF




                                        http://github.com/andrewtimberlake/css
method_missing                                  Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

puts   body['background']         #=>   background:#FFF
puts   body[:background]          #=>   background:#FFF
puts   body['background-color']   #=>   #FFF
puts   body.background            #=>   background:#FFF
puts   body.background_color      #=>   #FFF
puts   body.backgroundColor       #=>   #FFF
puts   body.background.color      #=>   #FFF




                                        http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

body.background.image = 'url(image.png)'




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

css = CSS::Parser.parse("body { background: #FFF }")
body = css['body']

body.background.image = 'url(image.png)'
puts body.background #=> background:#FFF url(image.png)




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

def method_missing(method_name, *args, &block)
  get(normalize_property_name(method_name.to_s))
end




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

def respond_to?(method_name, include_private = false)
  property_name = normalize_property_name(method_name.to_s)

  default_properties.keys.include?(property_name)
end




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

def respond_to?(method_name, include_private = false)
  property_name = normalize_property_name(method_name.to_s)

  default_properties.keys.include?(property_name) || super
end




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

def method_missing(method_name, *args, &block)
  property_name = method_name.to_s

  if respond_to?(method_name)
    property_name = normalize_property_name(property_name)
    get(property_name)
  end
end




                                  http://github.com/andrewtimberlake/css
method_missing                            Elegant APIs

def method_missing(method_name, *args, &block)
  property_name = method_name.to_s

  if respond_to?(method_name)
    property_name = normalize_property_name(property_name)
    get(property_name)
  else
    super
  end
end




                                  http://github.com/andrewtimberlake/css
method_missing                             Elegant APIs

def method_missing(method_name, *args, &block)
  property_name = method_name.to_s
  setter = property_name.chomp!('=')

  if respond_to?(method_name)
    property_name = normalize_property_name(property_name)

    if setter
       @properties[property_name] = ...
    else
      get(property_name)
    end
  else
    super
  end
end
                                   http://github.com/andrewtimberlake/css
Elegant APIs


variable arguments
method_missing
blocks
instance_eval
blocks              Elegant APIs


   variable arguments
   method_missing


   instance_eval
blocks                                   Elegant APIs

ec2 = Awsum::Ec2.new('123456', '654321')
ec2.run_instances 'ami-123456'




                                     http://github.com/internuity/awsum
blocks                                   Elegant APIs

ec2 = Awsum::Ec2.new('123456', '654321')
ec2.run_instances 'ami-123456'

region = ec2.region('eu-west')
region.run_instances 'ami-123456'
region.create_volume 'eu-west-1a'
region.allocate_address




                                     http://github.com/internuity/awsum
blocks                                      Elegant APIs

region = ec2.region('eu-west')
region.run_instances 'ami-123456'
region.create_volume 'eu-west-1a'
region.allocate_address

ec2.region('eu-west').use do |region|
  region.run_instances 'ami-123456'
  region.create_volume 'eu-west-1a'
  region.allocate_address
end




                                        http://github.com/internuity/awsum
blocks                                      Elegant APIs

ec2.region('eu-west').use do |region|
  run_instances
end

class Awsum::Ec2::Region
  def use(&block)
    old_host = @ec2.host
    @ec2.host = end_point
    yield self
  ensure
    @ec2.host = old_host
  end
end




                                        http://github.com/internuity/awsum
blocks                                      Elegant APIs

ec2.region('eu-west').use do |region|
  region.run_instances 'ami-123456'
  region.create_volume 'eu-west-1a'
  region.allocate_address
end




                                        http://github.com/internuity/awsum
blocks                                      Elegant APIs

ec2.region('eu-west').use do |region|
  region.run_instances 'ami-123456'
  region.create_volume 'eu-west-1a'
  region.allocate_address
end
ec2.region('eu-west').use do
  run_instances 'ami-123456'
  create_volume 'eu-west-1a'
  allocate_address
end




                                        http://github.com/internuity/awsum
Elegant APIs


variable arguments
method_missing
blocks
instance_eval
instance_eval        Elegant APIs


    variable arguments
    method_missing
    blocks
instance_eval                      Elegant APIs

ec2.region('eu-west').use do
  run_instances
end

class Awsum::Ec2::Region
  def use(&block)
    old_host = @ec2.host
    @ec2.host = end_point
    instance_eval(&block)
  ensure
    @ec2.host = old_host
  end
end




                               http://github.com/internuity/awsum
instance_eval                             Elegant APIs

ec2.region('eu-west').use do
  run_instances
end

class Awsum::Ec2::Region
  def use(&block)
    old_host = @ec2.host
    @ec2.host = end_point
    block.arity < 1 ? instance_eval(&block) : block[self]
  ensure
    @ec2.host = old_host
  end
end




                                      http://github.com/internuity/awsum
instance_eval                             Elegant APIs

class Awsum::Ec2::Region
  def use(&block)
    if block_given?
      begin
         old_host = @ec2.host
         @ec2.host = end_point
         block.arity < 1 ? instance_eval(&block) : block[self]
      ensure
         @ec2.host = old_host
      end
    else
      @ec2.host = end_point
      self
    end
  end
end
                                      http://github.com/internuity/awsum
instance_eval                      Elegant APIs

ec2.region('eu-west').use do
  run_instances
end




                               http://github.com/internuity/awsum
instance_eval                      Elegant APIs

ec2.region('eu-west').use do
  run_instances
end

ec2.region('eu-west') do
  run_instances
end




                               http://github.com/internuity/awsum
instance_eval                            Elegant APIs

ec2.region('eu-west') do
  run_instances
end

def region(region_name)
  region = regions(region_name)[0]
end




                                     http://github.com/internuity/awsum
instance_eval                            Elegant APIs

ec2.region('eu-west') do
  run_instances
end

def region(region_name, &block)
  region = regions(region_name)[0]
  if block_given?
    region.use(&block)
  else
    region
  end
end




                                     http://github.com/internuity/awsum
instance_eval                            Elegant APIs

class Awsum::Ec2::Region
  def method_missing(method_name, *args, &block)
    use do
      @ec2.send(method_name, *args, &block)
    end
  end

  def respond_to?(method_name,
                  include_private = false)
    @ec2.respond_to?(method_name, include_private) 
                     || super
  end
end




                                     http://github.com/internuity/awsum
Elegant APIs

     Inspiration
     (recommended reading)


     Ruby Best Practices
http://ruby best practices book.com
Practicing Ruby newsletter
  http://letter.ly/practicing-ruby


   Thanks Gregory Brown
Elegant APIs


                Thank you
                  twitter:   @atimberlake
  email:   andrew@andrewtimberlake.com

        web:   http://andrewtimberlake.com
code:   http://github.com/andrewtimberlake

Mais conteúdo relacionado

Mais procurados

AngularJS Tips&Tricks
AngularJS Tips&TricksAngularJS Tips&Tricks
AngularJS Tips&TricksPetr Bela
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With PhpJeremy Coates
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたmemememomo
 
To Batch Or Not To Batch
To Batch Or Not To BatchTo Batch Or Not To Batch
To Batch Or Not To BatchLuca Mearelli
 
Controlling The Cloud With Python
Controlling The Cloud With PythonControlling The Cloud With Python
Controlling The Cloud With PythonLuca Mearelli
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your AppLuca Mearelli
 
Web Scraping is BS
Web Scraping is BSWeb Scraping is BS
Web Scraping is BSJohn D
 
An introduction to Rex - FLOSS UK DevOps York 2015
An introduction to Rex - FLOSS UK DevOps York 2015An introduction to Rex - FLOSS UK DevOps York 2015
An introduction to Rex - FLOSS UK DevOps York 2015Andy Beverley
 
Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)osfameron
 
What’s new in ECMAScript 6.0
What’s new in ECMAScript 6.0What’s new in ECMAScript 6.0
What’s new in ECMAScript 6.0Eyal Vardi
 
Testing Jboss Seam Bottom Up
Testing Jboss Seam Bottom UpTesting Jboss Seam Bottom Up
Testing Jboss Seam Bottom UpDan Hinojosa
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Hack in the Box Keynote 2006
Hack in the Box Keynote 2006Hack in the Box Keynote 2006
Hack in the Box Keynote 2006Mark Curphey
 
Power Theming
Power ThemingPower Theming
Power Themingdrkdn
 
Investigating Python Wats
Investigating Python WatsInvestigating Python Wats
Investigating Python WatsAmy Hanlon
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)andrewnacin
 
And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...Codemotion
 

Mais procurados (20)

AngularJS Tips&Tricks
AngularJS Tips&TricksAngularJS Tips&Tricks
AngularJS Tips&Tricks
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With Php
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみた
 
To Batch Or Not To Batch
To Batch Or Not To BatchTo Batch Or Not To Batch
To Batch Or Not To Batch
 
Controlling The Cloud With Python
Controlling The Cloud With PythonControlling The Cloud With Python
Controlling The Cloud With Python
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
Web Scraping is BS
Web Scraping is BSWeb Scraping is BS
Web Scraping is BS
 
An introduction to Rex - FLOSS UK DevOps York 2015
An introduction to Rex - FLOSS UK DevOps York 2015An introduction to Rex - FLOSS UK DevOps York 2015
An introduction to Rex - FLOSS UK DevOps York 2015
 
Dancer's Ecosystem
Dancer's EcosystemDancer's Ecosystem
Dancer's Ecosystem
 
Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)
 
What’s new in ECMAScript 6.0
What’s new in ECMAScript 6.0What’s new in ECMAScript 6.0
What’s new in ECMAScript 6.0
 
Testing Jboss Seam Bottom Up
Testing Jboss Seam Bottom UpTesting Jboss Seam Bottom Up
Testing Jboss Seam Bottom Up
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Hack in the Box Keynote 2006
Hack in the Box Keynote 2006Hack in the Box Keynote 2006
Hack in the Box Keynote 2006
 
Power Theming
Power ThemingPower Theming
Power Theming
 
Investigating Python Wats
Investigating Python WatsInvestigating Python Wats
Investigating Python Wats
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...
 

Destaque

Destaque (7)

Practica 17
Practica 17Practica 17
Practica 17
 
Tema2
Tema2Tema2
Tema2
 
Photoshop for Photographers
Photoshop for PhotographersPhotoshop for Photographers
Photoshop for Photographers
 
He was there all the time
He was there all the timeHe was there all the time
He was there all the time
 
Practica 17
Practica 17Practica 17
Practica 17
 
Why join Cpl?
Why join Cpl?Why join Cpl?
Why join Cpl?
 
Practica 17
Practica 17Practica 17
Practica 17
 

Semelhante a Elegant APIs

All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxDr Nic Williams
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine YardHow I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine YardSV Ruby on Rails Meetup
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyNikhil Mungel
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the CloudWesley Beary
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)Wesley Beary
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013
Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013
Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013Amazon Web Services
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma IntroduçãoÍgor Bonadio
 

Semelhante a Elegant APIs (20)

All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine YardHow I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
 
Practical Celery
Practical CeleryPractical Celery
Practical Celery
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Ruby 2.0
Ruby 2.0Ruby 2.0
Ruby 2.0
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in Ruby
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloud
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013
Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013
Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
 
Lettering js
Lettering jsLettering js
Lettering js
 

Último

FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
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
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
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
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 

Último (20)

FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
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
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
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
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 

Elegant APIs

  • 1. Elegant APIs Why your methods should never go missing Presented by Andrew Timberlake
  • 4. variable arguments Elegant APIs method_missing blocks instance_eval
  • 5. variable arguments Elegant APIs def method(arg1) #... end
  • 6. variable arguments Elegant APIs def method(arg1 = 1) #... end
  • 7. variable arguments Elegant APIs def method(arg1 = 1, arg2 = 2) #... end
  • 8. variable arguments Elegant APIs def method(opts = {}) options = {:arg1 => 1, :arg2 => 2}.merge(opts) #... end
  • 9. variable arguments Elegant APIs def method(opts = {}) options = {:arg1 => 1, :arg2 => 2}.merge(opts) #... end method :arg2 => 3
  • 10. variable arguments Elegant APIs #Active Record User.create(:first_name => 'Andrew', :last_name => 'Timberlake')
  • 12. method_missing Elegant APIs variable arguments blocks instance_eval
  • 13. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] http://github.com/andrewtimberlake/css
  • 14. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] puts body['background'] #=> background:#FFF http://github.com/andrewtimberlake/css
  • 15. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] puts body['background'] #=> background:#FFF puts body[:background] #=> background:#FFF http://github.com/andrewtimberlake/css
  • 16. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] puts body['background'] #=> background:#FFF puts body[:background] #=> background:#FFF puts body['background-color'] #=> #FFF http://github.com/andrewtimberlake/css
  • 17. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] puts body['background'] #=> background:#FFF puts body[:background] #=> background:#FFF puts body['background-color'] #=> #FFF puts body.background #=> background:#FFF http://github.com/andrewtimberlake/css
  • 18. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] puts body['background'] #=> background:#FFF puts body[:background] #=> background:#FFF puts body['background-color'] #=> #FFF puts body.background #=> background:#FFF puts body.background_color #=> #FFF http://github.com/andrewtimberlake/css
  • 19. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] puts body['background'] #=> background:#FFF puts body[:background] #=> background:#FFF puts body['background-color'] #=> #FFF puts body.background #=> background:#FFF puts body.background_color #=> #FFF puts body.backgroundColor #=> #FFF http://github.com/andrewtimberlake/css
  • 20. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] puts body['background'] #=> background:#FFF puts body[:background] #=> background:#FFF puts body['background-color'] #=> #FFF puts body.background #=> background:#FFF puts body.background_color #=> #FFF puts body.backgroundColor #=> #FFF puts body.background.color #=> #FFF http://github.com/andrewtimberlake/css
  • 21. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] body.background.image = 'url(image.png)' http://github.com/andrewtimberlake/css
  • 22. method_missing Elegant APIs css = CSS::Parser.parse("body { background: #FFF }") body = css['body'] body.background.image = 'url(image.png)' puts body.background #=> background:#FFF url(image.png) http://github.com/andrewtimberlake/css
  • 23. method_missing Elegant APIs def method_missing(method_name, *args, &block) get(normalize_property_name(method_name.to_s)) end http://github.com/andrewtimberlake/css
  • 24. method_missing Elegant APIs def respond_to?(method_name, include_private = false) property_name = normalize_property_name(method_name.to_s) default_properties.keys.include?(property_name) end http://github.com/andrewtimberlake/css
  • 25. method_missing Elegant APIs def respond_to?(method_name, include_private = false) property_name = normalize_property_name(method_name.to_s) default_properties.keys.include?(property_name) || super end http://github.com/andrewtimberlake/css
  • 26. method_missing Elegant APIs def method_missing(method_name, *args, &block) property_name = method_name.to_s if respond_to?(method_name) property_name = normalize_property_name(property_name) get(property_name) end end http://github.com/andrewtimberlake/css
  • 27. method_missing Elegant APIs def method_missing(method_name, *args, &block) property_name = method_name.to_s if respond_to?(method_name) property_name = normalize_property_name(property_name) get(property_name) else super end end http://github.com/andrewtimberlake/css
  • 28. method_missing Elegant APIs def method_missing(method_name, *args, &block) property_name = method_name.to_s setter = property_name.chomp!('=') if respond_to?(method_name) property_name = normalize_property_name(property_name) if setter @properties[property_name] = ... else get(property_name) end else super end end http://github.com/andrewtimberlake/css
  • 30. blocks Elegant APIs variable arguments method_missing instance_eval
  • 31. blocks Elegant APIs ec2 = Awsum::Ec2.new('123456', '654321') ec2.run_instances 'ami-123456' http://github.com/internuity/awsum
  • 32. blocks Elegant APIs ec2 = Awsum::Ec2.new('123456', '654321') ec2.run_instances 'ami-123456' region = ec2.region('eu-west') region.run_instances 'ami-123456' region.create_volume 'eu-west-1a' region.allocate_address http://github.com/internuity/awsum
  • 33. blocks Elegant APIs region = ec2.region('eu-west') region.run_instances 'ami-123456' region.create_volume 'eu-west-1a' region.allocate_address ec2.region('eu-west').use do |region| region.run_instances 'ami-123456' region.create_volume 'eu-west-1a' region.allocate_address end http://github.com/internuity/awsum
  • 34. blocks Elegant APIs ec2.region('eu-west').use do |region| run_instances end class Awsum::Ec2::Region def use(&block) old_host = @ec2.host @ec2.host = end_point yield self ensure @ec2.host = old_host end end http://github.com/internuity/awsum
  • 35. blocks Elegant APIs ec2.region('eu-west').use do |region| region.run_instances 'ami-123456' region.create_volume 'eu-west-1a' region.allocate_address end http://github.com/internuity/awsum
  • 36. blocks Elegant APIs ec2.region('eu-west').use do |region| region.run_instances 'ami-123456' region.create_volume 'eu-west-1a' region.allocate_address end ec2.region('eu-west').use do run_instances 'ami-123456' create_volume 'eu-west-1a' allocate_address end http://github.com/internuity/awsum
  • 38. instance_eval Elegant APIs variable arguments method_missing blocks
  • 39. instance_eval Elegant APIs ec2.region('eu-west').use do run_instances end class Awsum::Ec2::Region def use(&block) old_host = @ec2.host @ec2.host = end_point instance_eval(&block) ensure @ec2.host = old_host end end http://github.com/internuity/awsum
  • 40. instance_eval Elegant APIs ec2.region('eu-west').use do run_instances end class Awsum::Ec2::Region def use(&block) old_host = @ec2.host @ec2.host = end_point block.arity < 1 ? instance_eval(&block) : block[self] ensure @ec2.host = old_host end end http://github.com/internuity/awsum
  • 41. instance_eval Elegant APIs class Awsum::Ec2::Region def use(&block) if block_given? begin old_host = @ec2.host @ec2.host = end_point block.arity < 1 ? instance_eval(&block) : block[self] ensure @ec2.host = old_host end else @ec2.host = end_point self end end end http://github.com/internuity/awsum
  • 42. instance_eval Elegant APIs ec2.region('eu-west').use do run_instances end http://github.com/internuity/awsum
  • 43. instance_eval Elegant APIs ec2.region('eu-west').use do run_instances end ec2.region('eu-west') do run_instances end http://github.com/internuity/awsum
  • 44. instance_eval Elegant APIs ec2.region('eu-west') do run_instances end def region(region_name) region = regions(region_name)[0] end http://github.com/internuity/awsum
  • 45. instance_eval Elegant APIs ec2.region('eu-west') do run_instances end def region(region_name, &block) region = regions(region_name)[0] if block_given? region.use(&block) else region end end http://github.com/internuity/awsum
  • 46. instance_eval Elegant APIs class Awsum::Ec2::Region def method_missing(method_name, *args, &block) use do @ec2.send(method_name, *args, &block) end end def respond_to?(method_name, include_private = false) @ec2.respond_to?(method_name, include_private) || super end end http://github.com/internuity/awsum
  • 47. Elegant APIs Inspiration (recommended reading) Ruby Best Practices http://ruby best practices book.com Practicing Ruby newsletter http://letter.ly/practicing-ruby Thanks Gregory Brown
  • 48. Elegant APIs Thank you twitter: @atimberlake email: andrew@andrewtimberlake.com web: http://andrewtimberlake.com code: http://github.com/andrewtimberlake

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n