SlideShare a Scribd company logo
1 of 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

More Related Content

What's hot

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
 

What's hot (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...
 

Viewers also liked

Viewers also liked (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
 

Similar to 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
 

Similar to 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
 

Recently uploaded

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
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
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
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
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
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
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Recently uploaded (20)

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
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
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
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
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
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
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

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

Editor's Notes

  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