SlideShare ist ein Scribd-Unternehmen logo
1 von 87
API DESIGN
The James scale of likes and dislikes
WHAT DO WE LIKE?
WHAT DO WE LIKE?


• We   work with a lot of API’s
WHAT DO WE LIKE?


• We   work with a lot of API’s

• We  generally have strong
 opinions about what “feels”
 right to us
WHAT DO WE LIKE?


• We   work with a lot of API’s

• We  generally have strong
 opinions about what “feels”
 right to us

• How   do we decide?
I HAVE NO CLUE
So we’re just going to talk about what I like
I HAVE NO CLUE
So we’re just going to talk about what I like
API’S JAMES LIKES
RUBY’S STANDARD LIBRARY
    Where many treasures can be found
RUBY’S STANDARD LIBRARY
    Where many treasures can be found
FILEUTILS
Unix style file manipulations
require "fileutils"

                               FileUtils.cd   dir,      options
                               FileUtils.cd   dir,      options do
                                # ...
                               end
                               FileUtils.mkdir dir,      options
                               FileUtils.mkdir_p dir,     options
                               FileUtils.ln   src, dest, options
                               FileUtils.ln_s src, dest, options


    FILEUTILS
                               FileUtils.cp   src, dest, options
                               FileUtils.cp_r src, dest, options
                               FileUtils.mv    src, dest, options
                               FileUtils.rm    files,    options
Unix style file manipulations   FileUtils.rm_r files,
                               FileUtils.rm_rf files,
                                                         options
                                                         options
                               FileUtils.chmod mode, files, options
                               FileUtils.chmod_R mode, files, options
                               FileUtils.touch files,     options

                               #
                               #   or
                               #
                               #   FileUtils::Verbose...
                               #   FileUtils::NoWrite...
                               #   FileUtils::DryRun...
                               #
GOOD DOESN’T MEAN…
  Complex, powerful, all encompassing, etc.
GOOD DOESN’T MEAN…
  Complex, powerful, all encompassing, etc.
OPENURI
The Web as just another IO
#!/usr/bin/env ruby -wKU

                             require "open-uri"



   OPENURI
                             open(__FILE__) do |f|
                              p f.gets
                              # >> "#!/usr/bin/env ruby -wKUn"
                             end
The Web as just another IO   open("http://blog.grayproductions.net") do |u|
                              p u.gets
                              # >> "<!DOCTYPE HTML PUBLIC …"
                              p u.content_type
                              # >> "text/html"
                             end
FAMILIAR
IS GOOD
But don’t be afraid
to add little extras
FAMILIAR
IS GOOD
But don’t be afraid
to add little extras
PATHNAME
Object oriented paths
#!/usr/bin/env ruby -wKU

                        require "pathname"

                        # using plain Ruby
                        if File.exist? some_dir
                          data = File.read(
                                  File.join( File.dirname(some_dir),


PATHNAME
                                          "another_dir",
                                          File.basename(some_file) )
                                )
                          # ...
Object oriented paths   end

                        # or using Pathname
                        some_dir = Pathname.new("some_dir")
                        some_file = Pathname.new("some_file")
                        if some_dir.exist?
                          data = ( some_dir.dirname +
                                "another_dir" +
                                some_file.basename ).read
                          # ...
                        end
FRESH IDEAS
Sometimes you just need to try something different
FRESH IDEAS
Sometimes you just need to try something different
PSTORE
A hash in a file
#!/usr/bin/env ruby -wKU

                  require "pstore"


PSTORE            store = PStore.new("data_file.pstore")
                  store.transaction do # begin transaction
                   store[:single_object] = "My data..."
                   store[:obj_heirarchy] = { "Kev Jackson" =>
A hash in a file                        [ "rational.rb",
                                         "pstore.rb" ],
                                     "James Gray" =>
                                       [ "erb.rb",
                                         "pstore.rb" ] }
                  end              # commit changes to file
A POWERFUL COMBINATION
 There’s no easier and safer way to manage a little data
A POWERFUL COMBINATION
 There’s no easier and safer way to manage a little data
API’S JAMES DOESN’T LIKE
S3 LIBRARIES
It seems like all S3 wrappers for Ruby are missing some details
S3 LIBRARIES
It seems like all S3 wrappers for Ruby are missing some details
AWS
Streaming double-interface
#!/usr/bin/env ruby -wKU

                             require "rubygems"


        AWS
                             require "aws"

                             s3 = Aws::S3.new(
                               "KEY_ID",
Streaming double-interface   )
                               "SECRET_KEY"

                             bucket = s3.bucket("graysoftinc", :create)
                             open(__FILE__) do |f|
                               bucket.put(File.basename(__FILE__), f)
                             end
#!/usr/bin/env ruby -wKU

                             require "rubygems"
                             require "aws"



        AWS
                             s3 = Aws::S3Interface.new(
                               "KEY_ID",
                               "SECRET_KEY"
                             )
Streaming double-interface   ary_of_hshs = s3.list_bucket("graysoftinc")
                             if hsh = ary_of_hshs.first
                               open("downloaded.rb", "w") do |f|
                                s3.get("graysoftinc", hsh[:key]) do |chunk|
                                  f << chunk
                                end
                               end
                             end
OUT OF
  PLACE
Why support half of
a feature in an API?
OUT OF
  PLACE
Why support half of
a feature in an API?
DON’T USE WITH THREADS!
   The many-threads-sharing-one-connection code is
a textbook perfect example of how not to do threading!
DON’T USE WITH THREADS!
   The many-threads-sharing-one-connection code is
a textbook perfect example of how not to do threading!
FOG
Warnings galore
#!/usr/bin/env ruby -wKU

                  require "rubygems"

   FOG            require "fog"

                  s3 = Fog::AWS::S3.new(
Warnings galore     :aws_access_key_id   => "SECRET",
                    :aws_secret_access_key => "SECRET"
                  )

                  p s3.directories.all
!!! DEPRECATION WARNING !!!
                  Hey Champ!  I see you're using Ruby 1.8.6!  While I applaud you for sticking to
                  your guns and using The One True Ruby, I have to let you know that we're going



   FOG
                  to stop supporting 1.8.6.  I know, it's sad.  But, we just don't have time to
                  support every version of Ruby out there.  Whether we like it or not, time moves
                  forward and so does our software.

                  On August 1, 2010, we will no longer support Ruby 1.8.6.  If nokogiri happens to

Warnings galore   work on 1.8.6 after that date, then great!  We will hownever, no longer test,
                  use, or endorse 1.8.6 as a supported platform.

                  Thanks,

                    Team Nokogiri
(eval):1: warning: method redefined; discarding old reject
                  (eval):1: warning: method redefined; discarding old select
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/collection.rb:40: warning:
                  method redefined; discarding old clear
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/collection.rb:55: warning:
                  method redefined; discarding old inspect
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws.rb:95: warning: redefine
                  image_id
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/terremark/parser.rb:6:
                  warning: method redefined; discarding old parse
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/s3.rb:7: warning:
                  instance variable @required not initialized




   FOG
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/models/s3/file.rb:20:
                  warning: method redefined; discarding old body
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/models/s3/file.rb:53:
                  warning: method redefined; discarding old owner=
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/models/s3/files.rb:80:
                  warning: method redefined; discarding old directory=

Warnings galore   /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/parsers/s3/
                  get_bucket_logging.rb:8: warning: method redefined; discarding old reset
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/parsers/s3/
                  get_bucket_logging.rb:13: warning: method redefined; discarding old end_element
                  /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog.rb:77: warning: instance
                  variable @mocking not initialized
                  /usr/local/lib/ruby/gems/1.8/gems/excon-0.0.26/lib/excon/connection.rb:90:
                  warning: using default DH parameters.
                    <Fog::AWS::S3::Directories
                      [
                        <Fog::AWS::S3::Directory
                          key="graysoftinc",
                          creation_date=Wed Jun 09 03:10:07 UTC 2010
                        >
                      ]
                    >
PERL WHIPS
  RUBY IN
ONE AREA
 Perl programmers
   use warnings!
PERL WHIPS
  RUBY IN
ONE AREA
 Perl programmers
   use warnings!
FREE
DEBUGGING
Who hates free bug finding?
#!/usr/bin/env ruby -wKU


   FREE
                             class Name
                              def initialize(first, last)
                                @first = first

DEBUGGING                       @last = last
                              end

Who hates free bug finding?    def full
                               "#{@firt} #{@last}".strip
                              end
                             end

                             name = Name.new("James", "Gray")
                             puts name.full
#!/usr/bin/env ruby -KU

                             class Name
                              def initialize(first, last)
                                @first = first
   FREE                         @last = last
                              end

DEBUGGING                     def first
                               @firt
                              end
Who hates free bug finding?   end

                             name = Name.new("James", "Gray")
                             Thread.new(name.first) do |first|
                              sleep 3
                              puts first.capitalize
                             end

                             sleep
LESS HOOPS
 TO JUGGLE
  In programming,
 that’s always a win
LESS HOOPS
 TO JUGGLE
  In programming,
 that’s always a win
RANDOM COMPARISONS
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
RANDOM COMPARISONS
               AWS          Fog           S3         AWS::S3
                        Not just no,    Present,
   Docs        Good                                    Good
                        but hell no!   but weird
  Works      Not for me     Yes           Yes           Yes
Streaming    With pain       Yes          No            Yes
                           Logs and
 Features       Logs                   Basics only   Fancy logs
                           versions
Thread-safe Don’t do it!     Yes          No            No
 Warnings       Yes        Uh, yeah!       Yes       Yes, a lot
                                       Command-
  Extras        No           Shell                      No
                                        line tool
DO WE HAVE A WINNER?
  None of them feel ribbon worthy to me
DO WE HAVE A WINNER?
  None of them feel ribbon worthy to me
DESIGN CHOICES
LET’S TALK TWITTER
Ruby’s Twitter libraries take pretty different approaches
LET’S TALK TWITTER
Ruby’s Twitter libraries take pretty different approaches
THE
TWITTER GEM
A typical object oriented API
#!/usr/bin/env ruby -wKU

                                require "rubygems"


    THE
                                require "twitter"

                                oauth = Twitter::OAuth.new( "consumer token",
                                                  "consumer secret" )


TWITTER GEM
                                oauth.authorize_from_access( "access token",
                                                  "access secret" )

                                client = Twitter::Base.new(oauth)
                                client.friends_timeline.each do |tweet|
A typical object oriented API    p tweet
                                end
                                client.user_timeline.each do |tweet|
                                 p tweet
                                end
                                client.replies.each do |tweet|
                                 p tweet
                                end

                                client.update("Heeeyyyyoooo from Twitter Gem!")
WHAT WE
LIKE TO RIDE
 Most API wrappers
   work like this
WHAT WE
LIKE TO RIDE
 Most API wrappers
   work like this
THE GRACKLE GEM
Grackle is a dynamic wrapper over Twitter’s raw API
#!/usr/bin/env ruby -wKU

require "rubygems"
require "grackle"

client = Grackle::Client.new( :auth => {
 :type        => :oauth,
 :consumer_key => "KEY",
 :consumer_secret => "SECRET",
 :token        => "TOKEN",
 :token_secret => "TOKEN_SECRET"
})

# http://twitter.com/users/show.json?screen_name=some_user
client.users.show? :screen_name => "some_user"
# POST to http://twitter.com/statuses/update.json
client.statuses.update! :status => "this status is from grackle"

client[:rest].users.show? :id => "hayesdavis"
client[:v1].users.show? :id => "hayesdavis"




        THE GRACKLE GEM
Grackle is a dynamic wrapper over Twitter’s raw API
TEACH
 GRACKLE
NEW TRICKS
All Twitter API updates are
     instantly supported
TEACH
 GRACKLE
NEW TRICKS
All Twitter API updates are
     instantly supported
WHAT ABOUT MONGODB?
How do we bridge the gap to this new kind of storage?
WHAT ABOUT MONGODB?
How do we bridge the gap to this new kind of storage?
MONGO-
  MAPPER
DataMapper for MongoDB
#!/usr/bin/env ruby -wKU

                         require "rubygems"
                         require "mongo_mapper"

                         MongoMapper.database = "testing"



  MONGO-
                         class User
                          include MongoMapper::Document

                          key :first_name, String,


  MAPPER
                             :required => true
                          key :last_name, String,
                             :required => true
                          key :token,      String,
DataMapper for MongoDB       :default => lambda { "some random string" }
                          key :age,       Integer
                          key :skills,   Array
                          key :friend_ids, Array, :typecast => "ObjectId"
                          timestamps!
                         end
                         User.collection.remove # empties collection

                         john = User.create(
                           :first_name => "John",
                           :last_name => "Nunemaker",
                           :age     => 28,
                           :skills  => ["ruby", "mongo", "javascript"],
                         )
ALMOST THE NORM
This is the kind of data access ActiveRecord has
               trained us to expect
ALMOST THE NORM
This is the kind of data access ActiveRecord has
               trained us to expect
CANDY
A very different approach
#!/usr/bin/env ruby -wKU

require "rubygems"
require "candy"

class Person
 include Candy::Piece
end

me        = Person.new
me.last_name = "Eley"   # New record created and saved to Mongo
me.id              # => ObjectID(4bb606f9609c8417cf00004b)
me[:height] = 67       # Or me.height = 67

me.favorites = { composer: "Yoko Kanno",
           seafood: "Maryland blue crabs",
           scotch: ["Glenmorangie Port Wood Finish",
                  "Balvenie Single Barrel"]}
me.spouse = Person.piece(first_name: "Anna", eyes: :blue)
me.spouse.eyes          # => :blue
me.favorites.scotch[1] # => "Balvenie Single Barrel"

Person.last_name("Smith") # Returns the first Smith
Person.age(21)        # Returns the first legal drinker (in the U.S.)
Person(12345)         # Returns the person with an _id of 12345



                                CANDY
                        A very different approach
#!/usr/bin/env ruby -wKU

require "rubygems"
require "candy"

class People
 include Candy::Collection
 collects :person # Declares the Mongo collection is 'Person'
end             # (and so is the Candy::Piece class)

People.last_name('Smith')                 # Returns an enumeration of all Smiths
People.age(19).sort(:birthdate, :down).limit(10) # We can chain options
People(limit: 47, occupation: :ronin)        # Or People.all(params) or People.new(params)
People.each(|p| p.shout = 'Norm!')           # Where everybody knows your name...




                                           CANDY
                                   A very different approach
ALL ABOUT
THE MAGIC
There’s no save() method!
ALL ABOUT
THE MAGIC
There’s no save() method!
THIS ENDS THE TOUR
THIS ENDS THE TOUR

• It’s
     hard to know what’s
  good or bad in an API
THIS ENDS THE TOUR

• It’s
     hard to know what’s
  good or bad in an API

• They  definitely seem to have
  a “feel” to them though
THIS ENDS THE TOUR

• It’s
     hard to know what’s
  good or bad in an API

• They  definitely seem to have
  a “feel” to them though

  • Aim  for the natural feel, if
     you can find it
ALL IMAGES COURTESY OF
     BLACK AND WTF
     http://blackandwtf.tumblr.com/
DISCUSSION
    TOPIC
Can we see anything in here
that applies to PortableHole?
DISCUSSION
    TOPIC
Can we see anything in here
that applies to PortableHole?

Weitere ähnliche Inhalte

Was ist angesagt?

05.linux basic-operations-1
05.linux basic-operations-105.linux basic-operations-1
05.linux basic-operations-1Minsuk Lee
 
On secure application of PHP wrappers
On secure application  of PHP wrappersOn secure application  of PHP wrappers
On secure application of PHP wrappersPositive Hack Days
 
OO Perl with Moose
OO Perl with MooseOO Perl with Moose
OO Perl with MooseNelo Onyiah
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
How to simplify OSGi development using OBR - Peter Kriens
How to simplify OSGi development using OBR - Peter KriensHow to simplify OSGi development using OBR - Peter Kriens
How to simplify OSGi development using OBR - Peter Kriensmfrancis
 
Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Bozhidar Batsov
 
Writing and using php streams and sockets tek11
Writing and using php streams and sockets   tek11Writing and using php streams and sockets   tek11
Writing and using php streams and sockets tek11Elizabeth Smith
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2Elizabeth Smith
 
DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopJeroen Keppens
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet
 
BASH Guide Summary
BASH Guide SummaryBASH Guide Summary
BASH Guide SummaryOhgyun Ahn
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script ProgrammingLin Yo-An
 
Sdec2011 shashank-introducing hadoop
Sdec2011 shashank-introducing hadoopSdec2011 shashank-introducing hadoop
Sdec2011 shashank-introducing hadoopKorea Sdec
 

Was ist angesagt? (17)

05.linux basic-operations-1
05.linux basic-operations-105.linux basic-operations-1
05.linux basic-operations-1
 
On secure application of PHP wrappers
On secure application  of PHP wrappersOn secure application  of PHP wrappers
On secure application of PHP wrappers
 
OO Perl with Moose
OO Perl with MooseOO Perl with Moose
OO Perl with Moose
 
extending-php
extending-phpextending-php
extending-php
 
Bento lunch talk
Bento   lunch talkBento   lunch talk
Bento lunch talk
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
How to simplify OSGi development using OBR - Peter Kriens
How to simplify OSGi development using OBR - Peter KriensHow to simplify OSGi development using OBR - Peter Kriens
How to simplify OSGi development using OBR - Peter Kriens
 
Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)
 
Writing and using php streams and sockets tek11
Writing and using php streams and sockets   tek11Writing and using php streams and sockets   tek11
Writing and using php streams and sockets tek11
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
 
DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark Workshop
 
Dispatch in Clojure
Dispatch in ClojureDispatch in Clojure
Dispatch in Clojure
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
 
Augeas @RMLL 2012
Augeas @RMLL 2012Augeas @RMLL 2012
Augeas @RMLL 2012
 
BASH Guide Summary
BASH Guide SummaryBASH Guide Summary
BASH Guide Summary
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
 
Sdec2011 shashank-introducing hadoop
Sdec2011 shashank-introducing hadoopSdec2011 shashank-introducing hadoop
Sdec2011 shashank-introducing hadoop
 

Andere mochten auch

Pinterest, Instagram and Twitter
Pinterest, Instagram and TwitterPinterest, Instagram and Twitter
Pinterest, Instagram and TwitterMarcusThomasLLC
 
Slide share, pinterest and instagram
Slide share, pinterest and instagramSlide share, pinterest and instagram
Slide share, pinterest and instagramTiffanyPintor
 
(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...
(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...
(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...Carolyn Hank
 
Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...
Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...
Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...Global Risk Forum GRFDavos
 
Natural Hazard Management and Communication: Potentials for Prevention due to...
Natural Hazard Management and Communication: Potentials for Prevention due to...Natural Hazard Management and Communication: Potentials for Prevention due to...
Natural Hazard Management and Communication: Potentials for Prevention due to...Global Risk Forum GRFDavos
 
La différence entre Pinterest et Instagram
La différence entre Pinterest et InstagramLa différence entre Pinterest et Instagram
La différence entre Pinterest et InstagramPlik.co
 
Pin ups and Public Relations: Why Pinterest Matters
Pin ups and Public Relations: Why Pinterest Matters Pin ups and Public Relations: Why Pinterest Matters
Pin ups and Public Relations: Why Pinterest Matters Christopher Spencer
 
Sonos benefits from social media
Sonos benefits from social mediaSonos benefits from social media
Sonos benefits from social mediaR2 Research B.V.
 
Teaching in the Age of Facebook
Teaching in the Age of FacebookTeaching in the Age of Facebook
Teaching in the Age of FacebookCarolyn Hank
 
Dispatches form Blog Purgatory
Dispatches form Blog PurgatoryDispatches form Blog Purgatory
Dispatches form Blog PurgatoryCarolyn Hank
 
Speech Transcript to China\'s Trade Unions
Speech Transcript to China\'s Trade UnionsSpeech Transcript to China\'s Trade Unions
Speech Transcript to China\'s Trade Unionsmtukaki
 
Mobilising the creation of a risk governance culture
Mobilising the creation of a risk governance cultureMobilising the creation of a risk governance culture
Mobilising the creation of a risk governance cultureGlobal Risk Forum GRFDavos
 

Andere mochten auch (14)

Pinterest, Instagram and Twitter
Pinterest, Instagram and TwitterPinterest, Instagram and Twitter
Pinterest, Instagram and Twitter
 
Instagram + Pinterest
Instagram + PinterestInstagram + Pinterest
Instagram + Pinterest
 
Slide share, pinterest and instagram
Slide share, pinterest and instagramSlide share, pinterest and instagram
Slide share, pinterest and instagram
 
(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...
(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...
(July 2011) One Less "To-Do:" Perceptions on the Role of Archives and Librari...
 
Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...
Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...
Session: Multiple One Health Perspectives on Protected Areas, Nature Conserva...
 
Natural Hazard Management and Communication: Potentials for Prevention due to...
Natural Hazard Management and Communication: Potentials for Prevention due to...Natural Hazard Management and Communication: Potentials for Prevention due to...
Natural Hazard Management and Communication: Potentials for Prevention due to...
 
La différence entre Pinterest et Instagram
La différence entre Pinterest et InstagramLa différence entre Pinterest et Instagram
La différence entre Pinterest et Instagram
 
Pin ups and Public Relations: Why Pinterest Matters
Pin ups and Public Relations: Why Pinterest Matters Pin ups and Public Relations: Why Pinterest Matters
Pin ups and Public Relations: Why Pinterest Matters
 
Sonos benefits from social media
Sonos benefits from social mediaSonos benefits from social media
Sonos benefits from social media
 
Teaching in the Age of Facebook
Teaching in the Age of FacebookTeaching in the Age of Facebook
Teaching in the Age of Facebook
 
Dispatches form Blog Purgatory
Dispatches form Blog PurgatoryDispatches form Blog Purgatory
Dispatches form Blog Purgatory
 
IDRC Davos Kuula 27.8.2014
IDRC Davos Kuula 27.8.2014IDRC Davos Kuula 27.8.2014
IDRC Davos Kuula 27.8.2014
 
Speech Transcript to China\'s Trade Unions
Speech Transcript to China\'s Trade UnionsSpeech Transcript to China\'s Trade Unions
Speech Transcript to China\'s Trade Unions
 
Mobilising the creation of a risk governance culture
Mobilising the creation of a risk governance cultureMobilising the creation of a risk governance culture
Mobilising the creation of a risk governance culture
 

Ähnlich wie API Design: James' Scale of Likes and Dislikes

The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitStephen Scaffidi
 
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...Puppet
 
Ruby for Java Developers
Ruby for Java DevelopersRuby for Java Developers
Ruby for Java DevelopersRobert Reiz
 
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
 
Django Files — A Short Talk
Django Files — A Short TalkDjango Files — A Short Talk
Django Files — A Short TalkJames Aylett
 
20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasaggarrett honeycutt
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesAlfresco Software
 
AMD - Why, What and How
AMD - Why, What and HowAMD - Why, What and How
AMD - Why, What and HowMike Wilcox
 
Intro to Rails
Intro to Rails Intro to Rails
Intro to Rails epiineg1
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Drupal Multisite Setup
Drupal Multisite SetupDrupal Multisite Setup
Drupal Multisite Setupipsitamishra
 
Django Files — A Short Talk (slides only)
Django Files — A Short Talk (slides only)Django Files — A Short Talk (slides only)
Django Files — A Short Talk (slides only)James Aylett
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012alexismidon
 
php fundamental
php fundamentalphp fundamental
php fundamentalzalatarunk
 
Php introduction with history of php
Php introduction with history of phpPhp introduction with history of php
Php introduction with history of phppooja bhandari
 

Ähnlich wie API Design: James' Scale of Likes and Dislikes (20)

The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's Toolkit
 
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
 
Ruby for Java Developers
Ruby for Java DevelopersRuby for Java Developers
Ruby for Java Developers
 
20 ruby input output
20 ruby input output20 ruby input output
20 ruby input output
 
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
 
Django Files — A Short Talk
Django Files — A Short TalkDjango Files — A Short Talk
Django Files — A Short Talk
 
20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best Practices
 
AMD - Why, What and How
AMD - Why, What and HowAMD - Why, What and How
AMD - Why, What and How
 
Intro to Rails
Intro to Rails Intro to Rails
Intro to Rails
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Gophers, whales and.. clouds? Oh my!
Gophers, whales and.. clouds? Oh my!Gophers, whales and.. clouds? Oh my!
Gophers, whales and.. clouds? Oh my!
 
LibreCat::Catmandu
LibreCat::CatmanduLibreCat::Catmandu
LibreCat::Catmandu
 
Solr Masterclass Bangkok, June 2014
Solr Masterclass Bangkok, June 2014Solr Masterclass Bangkok, June 2014
Solr Masterclass Bangkok, June 2014
 
Drupal Multisite Setup
Drupal Multisite SetupDrupal Multisite Setup
Drupal Multisite Setup
 
Django Files — A Short Talk (slides only)
Django Files — A Short Talk (slides only)Django Files — A Short Talk (slides only)
Django Files — A Short Talk (slides only)
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012
 
php fundamental
php fundamentalphp fundamental
php fundamental
 
Php introduction with history of php
Php introduction with history of phpPhp introduction with history of php
Php introduction with history of php
 
php
phpphp
php
 

Mehr von James Gray

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A KeynoteJames Gray
 
Regular expressions
Regular expressionsRegular expressions
Regular expressionsJames Gray
 
Counting on God
Counting on GodCounting on God
Counting on GodJames Gray
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your MindJames Gray
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)James Gray
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHubJames Gray
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in RailsJames Gray
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And RenderingJames Gray
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with RailsJames Gray
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in RailsJames Gray
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersJames Gray
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails InterfaceJames Gray
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on RailsJames Gray
 

Mehr von James Gray (18)

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A Keynote
 
I Doubt That!
I Doubt That!I Doubt That!
I Doubt That!
 
Regular expressions
Regular expressionsRegular expressions
Regular expressions
 
Counting on God
Counting on GodCounting on God
Counting on God
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your Mind
 
Unblocked
UnblockedUnblocked
Unblocked
 
Module Magic
Module MagicModule Magic
Module Magic
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in Rails
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And Rendering
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with Rails
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in Rails
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and Controllers
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
Ruby
RubyRuby
Ruby
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on Rails
 

Kürzlich hochgeladen

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Kürzlich hochgeladen (20)

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

API Design: James' Scale of Likes and Dislikes

  • 1. API DESIGN The James scale of likes and dislikes
  • 2. WHAT DO WE LIKE?
  • 3. WHAT DO WE LIKE? • We work with a lot of API’s
  • 4. WHAT DO WE LIKE? • We work with a lot of API’s • We generally have strong opinions about what “feels” right to us
  • 5. WHAT DO WE LIKE? • We work with a lot of API’s • We generally have strong opinions about what “feels” right to us • How do we decide?
  • 6. I HAVE NO CLUE So we’re just going to talk about what I like
  • 7. I HAVE NO CLUE So we’re just going to talk about what I like
  • 9. RUBY’S STANDARD LIBRARY Where many treasures can be found
  • 10. RUBY’S STANDARD LIBRARY Where many treasures can be found
  • 11. FILEUTILS Unix style file manipulations
  • 12. require "fileutils" FileUtils.cd dir, options FileUtils.cd dir, options do # ... end FileUtils.mkdir dir, options FileUtils.mkdir_p dir, options FileUtils.ln src, dest, options FileUtils.ln_s src, dest, options FILEUTILS FileUtils.cp src, dest, options FileUtils.cp_r src, dest, options FileUtils.mv src, dest, options FileUtils.rm files, options Unix style file manipulations FileUtils.rm_r files, FileUtils.rm_rf files, options options FileUtils.chmod mode, files, options FileUtils.chmod_R mode, files, options FileUtils.touch files, options # # or # # FileUtils::Verbose... # FileUtils::NoWrite... # FileUtils::DryRun... #
  • 13. GOOD DOESN’T MEAN… Complex, powerful, all encompassing, etc.
  • 14. GOOD DOESN’T MEAN… Complex, powerful, all encompassing, etc.
  • 15. OPENURI The Web as just another IO
  • 16. #!/usr/bin/env ruby -wKU require "open-uri" OPENURI open(__FILE__) do |f| p f.gets # >> "#!/usr/bin/env ruby -wKUn" end The Web as just another IO open("http://blog.grayproductions.net") do |u| p u.gets # >> "<!DOCTYPE HTML PUBLIC …" p u.content_type # >> "text/html" end
  • 17. FAMILIAR IS GOOD But don’t be afraid to add little extras
  • 18. FAMILIAR IS GOOD But don’t be afraid to add little extras
  • 20. #!/usr/bin/env ruby -wKU require "pathname" # using plain Ruby if File.exist? some_dir data = File.read( File.join( File.dirname(some_dir), PATHNAME "another_dir", File.basename(some_file) ) ) # ... Object oriented paths end # or using Pathname some_dir = Pathname.new("some_dir") some_file = Pathname.new("some_file") if some_dir.exist? data = ( some_dir.dirname + "another_dir" + some_file.basename ).read # ... end
  • 21. FRESH IDEAS Sometimes you just need to try something different
  • 22. FRESH IDEAS Sometimes you just need to try something different
  • 23. PSTORE A hash in a file
  • 24. #!/usr/bin/env ruby -wKU require "pstore" PSTORE store = PStore.new("data_file.pstore") store.transaction do # begin transaction store[:single_object] = "My data..." store[:obj_heirarchy] = { "Kev Jackson" => A hash in a file [ "rational.rb", "pstore.rb" ], "James Gray" => [ "erb.rb", "pstore.rb" ] } end # commit changes to file
  • 25. A POWERFUL COMBINATION There’s no easier and safer way to manage a little data
  • 26. A POWERFUL COMBINATION There’s no easier and safer way to manage a little data
  • 28. S3 LIBRARIES It seems like all S3 wrappers for Ruby are missing some details
  • 29. S3 LIBRARIES It seems like all S3 wrappers for Ruby are missing some details
  • 31. #!/usr/bin/env ruby -wKU require "rubygems" AWS require "aws" s3 = Aws::S3.new( "KEY_ID", Streaming double-interface ) "SECRET_KEY" bucket = s3.bucket("graysoftinc", :create) open(__FILE__) do |f| bucket.put(File.basename(__FILE__), f) end
  • 32. #!/usr/bin/env ruby -wKU require "rubygems" require "aws" AWS s3 = Aws::S3Interface.new( "KEY_ID", "SECRET_KEY" ) Streaming double-interface ary_of_hshs = s3.list_bucket("graysoftinc") if hsh = ary_of_hshs.first open("downloaded.rb", "w") do |f| s3.get("graysoftinc", hsh[:key]) do |chunk| f << chunk end end end
  • 33. OUT OF PLACE Why support half of a feature in an API?
  • 34. OUT OF PLACE Why support half of a feature in an API?
  • 35. DON’T USE WITH THREADS! The many-threads-sharing-one-connection code is a textbook perfect example of how not to do threading!
  • 36. DON’T USE WITH THREADS! The many-threads-sharing-one-connection code is a textbook perfect example of how not to do threading!
  • 38. #!/usr/bin/env ruby -wKU require "rubygems" FOG require "fog" s3 = Fog::AWS::S3.new( Warnings galore :aws_access_key_id => "SECRET", :aws_secret_access_key => "SECRET" ) p s3.directories.all
  • 39. !!! DEPRECATION WARNING !!! Hey Champ!  I see you're using Ruby 1.8.6!  While I applaud you for sticking to your guns and using The One True Ruby, I have to let you know that we're going FOG to stop supporting 1.8.6.  I know, it's sad.  But, we just don't have time to support every version of Ruby out there.  Whether we like it or not, time moves forward and so does our software. On August 1, 2010, we will no longer support Ruby 1.8.6.  If nokogiri happens to Warnings galore work on 1.8.6 after that date, then great!  We will hownever, no longer test, use, or endorse 1.8.6 as a supported platform. Thanks,   Team Nokogiri
  • 40. (eval):1: warning: method redefined; discarding old reject (eval):1: warning: method redefined; discarding old select /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/collection.rb:40: warning: method redefined; discarding old clear /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/collection.rb:55: warning: method redefined; discarding old inspect /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws.rb:95: warning: redefine image_id /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/terremark/parser.rb:6: warning: method redefined; discarding old parse /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/s3.rb:7: warning: instance variable @required not initialized FOG /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/models/s3/file.rb:20: warning: method redefined; discarding old body /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/models/s3/file.rb:53: warning: method redefined; discarding old owner= /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/models/s3/files.rb:80: warning: method redefined; discarding old directory= Warnings galore /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/parsers/s3/ get_bucket_logging.rb:8: warning: method redefined; discarding old reset /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog/aws/parsers/s3/ get_bucket_logging.rb:13: warning: method redefined; discarding old end_element /usr/local/lib/ruby/gems/1.8/gems/fog-0.1.8/lib/fog.rb:77: warning: instance variable @mocking not initialized /usr/local/lib/ruby/gems/1.8/gems/excon-0.0.26/lib/excon/connection.rb:90: warning: using default DH parameters.   <Fog::AWS::S3::Directories     [       <Fog::AWS::S3::Directory         key="graysoftinc",         creation_date=Wed Jun 09 03:10:07 UTC 2010       >     ]   >
  • 41. PERL WHIPS RUBY IN ONE AREA Perl programmers use warnings!
  • 42. PERL WHIPS RUBY IN ONE AREA Perl programmers use warnings!
  • 44. #!/usr/bin/env ruby -wKU FREE class Name def initialize(first, last) @first = first DEBUGGING @last = last end Who hates free bug finding? def full "#{@firt} #{@last}".strip end end name = Name.new("James", "Gray") puts name.full
  • 45. #!/usr/bin/env ruby -KU class Name def initialize(first, last) @first = first FREE @last = last end DEBUGGING def first @firt end Who hates free bug finding? end name = Name.new("James", "Gray") Thread.new(name.first) do |first| sleep 3 puts first.capitalize end sleep
  • 46. LESS HOOPS TO JUGGLE In programming, that’s always a win
  • 47. LESS HOOPS TO JUGGLE In programming, that’s always a win
  • 49. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 50. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 51. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 52. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 53. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 54. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 55. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 56. RANDOM COMPARISONS AWS Fog S3 AWS::S3 Not just no, Present, Docs Good Good but hell no! but weird Works Not for me Yes Yes Yes Streaming With pain Yes No Yes Logs and Features Logs Basics only Fancy logs versions Thread-safe Don’t do it! Yes No No Warnings Yes Uh, yeah! Yes Yes, a lot Command- Extras No Shell No line tool
  • 57. DO WE HAVE A WINNER? None of them feel ribbon worthy to me
  • 58. DO WE HAVE A WINNER? None of them feel ribbon worthy to me
  • 60. LET’S TALK TWITTER Ruby’s Twitter libraries take pretty different approaches
  • 61. LET’S TALK TWITTER Ruby’s Twitter libraries take pretty different approaches
  • 62. THE TWITTER GEM A typical object oriented API
  • 63. #!/usr/bin/env ruby -wKU require "rubygems" THE require "twitter" oauth = Twitter::OAuth.new( "consumer token", "consumer secret" ) TWITTER GEM oauth.authorize_from_access( "access token", "access secret" ) client = Twitter::Base.new(oauth) client.friends_timeline.each do |tweet| A typical object oriented API p tweet end client.user_timeline.each do |tweet| p tweet end client.replies.each do |tweet| p tweet end client.update("Heeeyyyyoooo from Twitter Gem!")
  • 64. WHAT WE LIKE TO RIDE Most API wrappers work like this
  • 65. WHAT WE LIKE TO RIDE Most API wrappers work like this
  • 66. THE GRACKLE GEM Grackle is a dynamic wrapper over Twitter’s raw API
  • 67. #!/usr/bin/env ruby -wKU require "rubygems" require "grackle" client = Grackle::Client.new( :auth => { :type => :oauth, :consumer_key => "KEY", :consumer_secret => "SECRET", :token => "TOKEN", :token_secret => "TOKEN_SECRET" }) # http://twitter.com/users/show.json?screen_name=some_user client.users.show? :screen_name => "some_user" # POST to http://twitter.com/statuses/update.json client.statuses.update! :status => "this status is from grackle" client[:rest].users.show? :id => "hayesdavis" client[:v1].users.show? :id => "hayesdavis" THE GRACKLE GEM Grackle is a dynamic wrapper over Twitter’s raw API
  • 68. TEACH GRACKLE NEW TRICKS All Twitter API updates are instantly supported
  • 69. TEACH GRACKLE NEW TRICKS All Twitter API updates are instantly supported
  • 70. WHAT ABOUT MONGODB? How do we bridge the gap to this new kind of storage?
  • 71. WHAT ABOUT MONGODB? How do we bridge the gap to this new kind of storage?
  • 73. #!/usr/bin/env ruby -wKU require "rubygems" require "mongo_mapper" MongoMapper.database = "testing" MONGO- class User include MongoMapper::Document key :first_name, String, MAPPER :required => true key :last_name, String, :required => true key :token, String, DataMapper for MongoDB :default => lambda { "some random string" } key :age, Integer key :skills, Array key :friend_ids, Array, :typecast => "ObjectId" timestamps! end User.collection.remove # empties collection john = User.create( :first_name => "John", :last_name => "Nunemaker", :age => 28, :skills => ["ruby", "mongo", "javascript"], )
  • 74. ALMOST THE NORM This is the kind of data access ActiveRecord has trained us to expect
  • 75. ALMOST THE NORM This is the kind of data access ActiveRecord has trained us to expect
  • 77. #!/usr/bin/env ruby -wKU require "rubygems" require "candy" class Person include Candy::Piece end me = Person.new me.last_name = "Eley" # New record created and saved to Mongo me.id # => ObjectID(4bb606f9609c8417cf00004b) me[:height] = 67 # Or me.height = 67 me.favorites = { composer: "Yoko Kanno", seafood: "Maryland blue crabs", scotch: ["Glenmorangie Port Wood Finish", "Balvenie Single Barrel"]} me.spouse = Person.piece(first_name: "Anna", eyes: :blue) me.spouse.eyes # => :blue me.favorites.scotch[1] # => "Balvenie Single Barrel" Person.last_name("Smith") # Returns the first Smith Person.age(21) # Returns the first legal drinker (in the U.S.) Person(12345) # Returns the person with an _id of 12345 CANDY A very different approach
  • 78. #!/usr/bin/env ruby -wKU require "rubygems" require "candy" class People include Candy::Collection collects :person # Declares the Mongo collection is 'Person' end # (and so is the Candy::Piece class) People.last_name('Smith') # Returns an enumeration of all Smiths People.age(19).sort(:birthdate, :down).limit(10) # We can chain options People(limit: 47, occupation: :ronin) # Or People.all(params) or People.new(params) People.each(|p| p.shout = 'Norm!') # Where everybody knows your name... CANDY A very different approach
  • 79. ALL ABOUT THE MAGIC There’s no save() method!
  • 80. ALL ABOUT THE MAGIC There’s no save() method!
  • 82. THIS ENDS THE TOUR • It’s hard to know what’s good or bad in an API
  • 83. THIS ENDS THE TOUR • It’s hard to know what’s good or bad in an API • They definitely seem to have a “feel” to them though
  • 84. THIS ENDS THE TOUR • It’s hard to know what’s good or bad in an API • They definitely seem to have a “feel” to them though • Aim for the natural feel, if you can find it
  • 85. ALL IMAGES COURTESY OF BLACK AND WTF http://blackandwtf.tumblr.com/
  • 86. DISCUSSION TOPIC Can we see anything in here that applies to PortableHole?
  • 87. DISCUSSION TOPIC Can we see anything in here that applies to PortableHole?

Hinweis der Redaktion