SlideShare une entreprise Scribd logo
1  sur  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

Contenu connexe

Tendances

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
 

Tendances (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...
 

En vedette

En vedette (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
 

Similaire à 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
 

Similaire à 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
 

Dernier

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
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
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
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
 
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
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
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
 
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
 
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
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
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
 
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
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 

Dernier (20)

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
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
 
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
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
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
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 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...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
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
 
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
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 

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

Notes de l'éditeur

  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