SlideShare ist ein Scribd-Unternehmen logo
1 von 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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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...
 

Andere mochten auch

Andere mochten auch (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Kürzlich hochgeladen

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
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
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
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
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
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
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Principled Technologies
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
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
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 

Kürzlich hochgeladen (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
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
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
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
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
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
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
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
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 

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

Hinweis der Redaktion

  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