SlideShare ist ein Scribd-Unternehmen logo
1 von 95
Downloaden Sie, um offline zu lesen
stop reinventing
    the wheel
hidden gems in the ruby standard library


      brian hogan - @bphogan
Twitter: @bphogan
Web: http://www.napcs.com/
What about this
                        design?
            describe "the user" do
              it "gets an email when their account is activated" do
                # some stuff
              end
            end




Twitter: @bphogan
Web: http://www.napcs.com/
Sometimes ideas
             evolve for the better.




Twitter: @bphogan
Web: http://www.napcs.com/
Other times not so
                     much.




Twitter: @bphogan
Web: http://www.napcs.com/
In software we
                           reinvent




Twitter: @bphogan
Web: http://www.napcs.com/
How often is
                     “better”
               really just opinion?



Twitter: @bphogan
Web: http://www.napcs.com/
So, we’re not talking
              about always using
                 what exists...


Twitter: @bphogan
Web: http://www.napcs.com/
We’re talking about
            reinventing because
            of ignorance, hubris,
                   or ego.

Twitter: @bphogan
Web: http://www.napcs.com/
Ruby Standard Library

                             http://ruby-doc.org/stdlib/




Twitter: @bphogan
Web: http://www.napcs.com/
•FileUtils
       •Forwardable
       •Pathname
       •open-uri
       •TempFile
       •WEBrick


Twitter: @bphogan
Web: http://www.napcs.com/
Working With The File
               System
     system("mkdir -p tmp/files")
     system("touch tmp/files/lockfile.lock")
     system("rm -rf tmp/files")




Twitter: @bphogan
Web: http://www.napcs.com/
Make it platform-
                   independent!
      require 'fileutils'

      FileUtils.mkdir_p("tmp/files")
      FileUtils.touch("tmp/files/lockfile.lock")
      FileUtils.rm_rf("tmp/files")




Twitter: @bphogan
Web: http://www.napcs.com/
FileUtils
          Namespace for several file utility methods
          for copying, moving, removing, etc.




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used

           •Rake
           •Capistrano stuff
           •Sinatra Reloader gem
           •Compass

Twitter: @bphogan
Web: http://www.napcs.com/
Where does it fall
                     short?



Twitter: @bphogan
Web: http://www.napcs.com/
Delegating Methods
          Calling methods on one class through another.

                             User    Profile




                             name    name




Twitter: @bphogan
Web: http://www.napcs.com/
Here’s how Rails
                        does it
      def delegate(*methods)
        options = methods.pop
        unless options.is_a?(Hash) && to = options[:to]
          raise ArgumentError, "Delegation needs a target.
             Supply an options hash with a :to key as the last argument
              (e.g. delegate :hello, :to => :greeter)."
        end

        methods.each do |method|
          module_eval("def #{method}(*args, &block)
          n#{to}.__send__(#{method.inspect},
           *args, &block)nendn", "(__DELEGATION__)", 1)
        end
      end




Twitter: @bphogan
Web: http://www.napcs.com/
Here’s how Rails
                        does it
                       class User < ActiveRecord::Base
                         has_one :profile
                         delegate :name, :to => :profile
                       end




Twitter: @bphogan
Web: http://www.napcs.com/
Here’s how we could
                   do it.
                     require 'forwardable'

                     class User < ActiveRecord::Base
                       has_one :profile
                       extend Forwardable
                       def_delegator :profile, :bio, :bio
                     end




Twitter: @bphogan
Web: http://www.napcs.com/
Forwardable
                        This library allows you
                        delegate method calls to
                        an object, on a method by
                        method basis.




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used


           •MongoMapper
           •Rack::Client


Twitter: @bphogan
Web: http://www.napcs.com/
Where does it fall
                     short?



Twitter: @bphogan
Web: http://www.napcs.com/
Working with Paths




Twitter: @bphogan
Web: http://www.napcs.com/
Seen in tons of Rails
                    apps...
     file = File.join(RAILS_ROOT, "config", "database.yml")
     config = YAML.load(File.read(file))




Twitter: @bphogan
Web: http://www.napcs.com/
A better way
             file = Rails.root.join("config", "database.yml")
             config = YAML.load(file.read)



                               Rails.root.class
                                => Pathname

                                           http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/




Twitter: @bphogan
Web: http://www.napcs.com/
Pathname
          Library to simplify working
              with files and paths.
        Represents a pathname which locates a file
        in a filesystem. The pathname depends on
                   OS: Unix, Windows, etc.




Twitter: @bphogan
Web: http://www.napcs.com/
Neat stuff
        require 'pathname'
        p = Pathname.new("/usr/bin/ruby")
        size = p.size              # 27662
        isdir = p.directory?       # false
        dir = p.dirname            # Pathname:/usr/bin
        base = p.basename          # Pathname:ruby
        dir, base = p.split        # [Pathname:/usr/bin, Pathname:ruby]




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used

           •Rails
           •DataMapper
           •Warehouse
           •Webistrano
           •many many more
Twitter: @bphogan
Web: http://www.napcs.com/
Grabbing Files




Twitter: @bphogan
Web: http://www.napcs.com/
cURL?
                      puts `curl http://pastie.org/1131498.txt?
                      key=zst64zkddsxafra0jz678g`




Twitter: @bphogan
Web: http://www.napcs.com/
Not available
              everywhere,
          must handle redirects.



Twitter: @bphogan
Web: http://www.napcs.com/
Treat URLs as files!
  require 'open-uri'
  url = "http://pastie.org/1131498.txt?key=zst64zkddsxafra0jz678g"
  puts open(url).read




Twitter: @bphogan
Web: http://www.napcs.com/
open-uri


                 Wraps net/http, net/https, and net/ftp.




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used


           •Everywhere.


Twitter: @bphogan
Web: http://www.napcs.com/
Where does it fall
                     short?



Twitter: @bphogan
Web: http://www.napcs.com/
Temporary files




Twitter: @bphogan
Web: http://www.napcs.com/
The hard way
 path = "http://pastie.org/1131498.txt?key=zst64zkddsxafra0jz678g"
 `curl #{path} > /tmp/template.html`
 s = File.read("/tmp/template.html")
 puts s




Twitter: @bphogan
Web: http://www.napcs.com/
Use TempFile
 require 'open-uri'
 require 'tempfile'
 url = "http://pastie.org/1131498.txt?key=zst64zkddsxafra0jz678g"
 tempfile = Tempfile.new("template.html")
 tempfile.write open(url).read
 puts tempfile.open.read




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used


           •File uploading
           •Caching


Twitter: @bphogan
Web: http://www.napcs.com/
Data structures




Twitter: @bphogan
Web: http://www.napcs.com/
YAML loads to hashes
           require 'YAML'
           config = YAML.load(Pathname.new("config.yml").read)

           puts config["company_name"]
           puts config["banner_image_url"]
           puts config["custom_css_url"]




Twitter: @bphogan
Web: http://www.napcs.com/
Use OpenStruct!
              require 'ostruct'
              require 'YAML'
              config = YAML.load(Pathname.new("config.yml").read)
              config = OpenStruct.new(config)
              puts config.company_name
              puts config.banner_image_url
              puts config.custom_css_url




Twitter: @bphogan
Web: http://www.napcs.com/
Don’t write your own
            “YAML-to-Object”
          thing (like I once did!)




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used

           •Fat Free CMS
           •ActiveMessaging
           •Adhearsion
           •AASM

Twitter: @bphogan
Web: http://www.napcs.com/
Where does it fall
                     short?



Twitter: @bphogan
Web: http://www.napcs.com/
Watching Stuff




Twitter: @bphogan
Web: http://www.napcs.com/
Rails?




Twitter: @bphogan
Web: http://www.napcs.com/
def initialize
                            super
                            observed_descendants.each { |klass| add_observer!(klass) }
                          end


                          def self.method_added(method)
                            method = method.to_sym


                            if ActiveRecord::Callbacks::CALLBACKS.include?(method)
                                self.observed_methods += [method]
                                self.observed_methods.freeze
                            end
                          end


                          protected


                            def observed_descendants
                                observed_classes.sum([]) { |klass| klass.descendants }
                            end


                            def observe_callbacks?
                                self.class.observed_methods.any?
                            end


                            def add_observer!(klass)
                                super
                                define_callbacks klass if observe_callbacks?
                            end


                            def define_callbacks(klass)
                                existing_methods = klass.instance_methods.map { |m| m.to_sym }
                                observer = self
                                observer_name = observer.class.name.underscore.gsub('/', '__')


                                self.class.observed_methods.each do |method|
                                  callback = :"_notify_#{observer_name}_for_#{method}"
                                  unless existing_methods.include? callback
                                      klass.send(:define_method, callback) do   # def _notify_user_observer_for_before_save
                                        observer.update(method, self)           #   observer.update(:before_save, self)
                                      end                                       # end
                                      klass.send(method, callback)              # before_save :_notify_user_observer_for_before_save
                                  end
                                end
                            end
                      end
                    end




Twitter: @bphogan
Web: http://www.napcs.com/
Observer
                                Provides a simple
                                mechanism for one
                                object to inform a set of
                                interested third-party
                                objects when its state
                                changes.




Twitter: @bphogan
Web: http://www.napcs.com/
How we do it
           require 'observer'

           class ConfirmationEmailer
             def update(account)
               puts "Sending confirmation mail to: '#{account.email}'"
               # send the email mechanism
             end
           end




Twitter: @bphogan
Web: http://www.napcs.com/
class Account
                      include Observable
                      attr_accessor :email, :active

                       def initialize(email)
                         self.email = email
                         self.active = false
                         add_observer ConfirmationEmailer.new
                       end

                      def activate_account!
                        self.active = true
                        changed     # <- This is important
                        notify_observers self
                      end
                    end




Twitter: @bphogan
Web: http://www.napcs.com/
Where does it fall
                     short?



Twitter: @bphogan
Web: http://www.napcs.com/
Serving Web Pages




Twitter: @bphogan
Web: http://www.napcs.com/
Sinatra?
                             require 'sinatra'
                             set :public, "~/Sites"




Twitter: @bphogan
Web: http://www.napcs.com/
How about this?
  s = WEBrick::HTTPServer.new(:Port => 3000,
     :DocumentRoot => "~/Sites")
  trap('INT') { s.shutdown };
  s.start




Twitter: @bphogan
Web: http://www.napcs.com/
How about an alias?
 alias serve="ruby -rwebrick -e"s = WEBrick::HTTPServer.new(:Port => 3000, :DocumentRoot =>
 Dir.pwd); trap('INT') { s.shutdown }; s.start""



                                     $ cd ~/Sites
                                     $ serve




Twitter: @bphogan
Web: http://www.napcs.com/
Twitter: @bphogan
Web: http://www.napcs.com/
It also serves web
                          apps




Twitter: @bphogan
Web: http://www.napcs.com/
Your dev machine
            really needs Passenger
                    running?




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used


           •Rails
           •Other frameworks


Twitter: @bphogan
Web: http://www.napcs.com/
Where does it fall
                     short?



Twitter: @bphogan
Web: http://www.napcs.com/
Storing Data




Twitter: @bphogan
Web: http://www.napcs.com/
PStore
           Persistent, transactional
           storage. Baked right in to
            Ruby’s standard library.




Twitter: @bphogan
Web: http://www.napcs.com/
We can store stuff...
               require 'pstore'
               store = PStore.new('links')

               links = %W{http://www.github.com
                         http://heroku.com
                         http://ruby-lang.org}

               store.transaction do
                 store[:links] ||= []
                 links.each{|link| store[:links] << link}
                 store[:last_modified] = Time.now
               end




Twitter: @bphogan
Web: http://www.napcs.com/
and we can get it
                       back.
                   store = PStore.new("links")
                   store.transaction do
                     links = store[:links]
                   end

                   puts links.join("n")




Twitter: @bphogan
Web: http://www.napcs.com/
Where it’s used


           •Rails 1.x


Twitter: @bphogan
Web: http://www.napcs.com/
Where does it
                          fall short?


Twitter: @bphogan
Web: http://www.napcs.com/
Better Wheels




Twitter: @bphogan
Web: http://www.napcs.com/
Importing CSV files
     require 'csv'

       CSV.open('data.csv', 'r', ';') do |row|
         p row
       end




Twitter: @bphogan
Web: http://www.napcs.com/
CSV is slow.
                   “Use FasterCSV”


Twitter: @bphogan
Web: http://www.napcs.com/
In Ruby 1.9,
            FasterCSV is the new
                    CSV!

Twitter: @bphogan
Web: http://www.napcs.com/
Working with Dates




Twitter: @bphogan
Web: http://www.napcs.com/
How we do it
           today = DateTime.now
           birthday = Date.new(2010, 10, 5)
           days_to_go = birthday - today
           time_until = birthday - today
           hours,minutes,seconds,frac =
           Date.day_fraction_to_time(time_until)



                             http://www.techotopia.com/index.php/Working_with_Dates_and_Times_in_Ruby


Twitter: @bphogan
Web: http://www.napcs.com/
home_run
            home_run is an implementation of rubyʼs Date/
            DateTime classes in C, with much better
            performance (20-200x) than the version in the
            standard library, while being almost completely
            compatible.

              http://github.com/jeremyevans/home_run




Twitter: @bphogan
Web: http://www.napcs.com/
REXML

            Built-in library for
        parsing and creating XML.




Twitter: @bphogan
Web: http://www.napcs.com/
How about
     HPricot, libxml-
        ruby, or
       Nokogiri.
                             http://www.rubyinside.com/ruby-xml-performance-benchmarks-1641.html




Twitter: @bphogan
Web: http://www.napcs.com/
ERb


      Templating language as part of the Standard Library.




Twitter: @bphogan
Web: http://www.napcs.com/
require 'erb'

                        template = ERB.new <<-EOF
                         <h1><%=@name %></h1>
                        EOF

                        @name = "AwesomeCo"

                        puts template.result




Twitter: @bphogan
Web: http://www.napcs.com/
Templating language
                     !=
              View language!!!



Twitter: @bphogan
Web: http://www.napcs.com/
What can it do?

           •Generate JavaScript
           •Generate YAML
           •Generate ERb
           •Any type of proprietary data export

Twitter: @bphogan
Web: http://www.napcs.com/
Where does it fall
                     short?



Twitter: @bphogan
Web: http://www.napcs.com/
Alternatives?

           •HAML
           •Liquid
           •ERubis
           •Tons of others

Twitter: @bphogan
Web: http://www.napcs.com/
Test::Unit

                 We have an awesome testing library
                   as part of our standard library.




Twitter: @bphogan
Web: http://www.napcs.com/
It’s pretty good.
            Anyone know of any
                 alternatives?



Twitter: @bphogan
Web: http://www.napcs.com/
Only a few.
           •RSpec
           •Bacon
           •Context / Contest / Shoulda / Matchy
           •Testy
           •Micronaut
           •Whatever someone writes next week

Twitter: @bphogan
Web: http://www.napcs.com/
I use RSpec *


                             * And I still use Test::Unit.




Twitter: @bphogan
Web: http://www.napcs.com/
“Minitest is a minitest/unit
             is a small and fast
           replacement for ruby's
          huge and slow test/unit”.



Twitter: @bphogan
Web: http://www.napcs.com/
If X sucks so bad, why
                 do we write
               something else
             instead of fixing it?


Twitter: @bphogan
Web: http://www.napcs.com/
We think we can do it
                 better.



Twitter: @bphogan
Web: http://www.napcs.com/
The original developer
         doesn’t want our help.


Twitter: @bphogan
Web: http://www.napcs.com/
There’s a language
                      barrier.


Twitter: @bphogan
Web: http://www.napcs.com/
Challenge:
              Extend the Standard
                    Library.


Twitter: @bphogan
Web: http://www.napcs.com/
Make the wheels we
                have better.




Twitter: @bphogan
Web: http://www.napcs.com/
That’s it.

           •Twitter: @bphogan
           •email: bphogan@gmail.com
           •web: http://www.napcs.com/
           •blog: http://bphogan.com
           •github: http://github.com/napcs/
Twitter: @bphogan
Web: http://www.napcs.com/

Weitere ähnliche Inhalte

Was ist angesagt?

Getting started with Django 1.8
Getting started with Django 1.8Getting started with Django 1.8
Getting started with Django 1.8rajkumar2011
 
Rush, a shell that will yield to you
Rush, a shell that will yield to youRush, a shell that will yield to you
Rush, a shell that will yield to youguestdd9d06
 
Big data beyond the JVM - DDTX 2018
Big data beyond the JVM -  DDTX 2018Big data beyond the JVM -  DDTX 2018
Big data beyond the JVM - DDTX 2018Holden Karau
 
Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2RORLAB
 
Opening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the IslandsOpening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the IslandsBastian Hofmann
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 

Was ist angesagt? (10)

Getting started with Django 1.8
Getting started with Django 1.8Getting started with Django 1.8
Getting started with Django 1.8
 
Rush, a shell that will yield to you
Rush, a shell that will yield to youRush, a shell that will yield to you
Rush, a shell that will yield to you
 
Big data beyond the JVM - DDTX 2018
Big data beyond the JVM -  DDTX 2018Big data beyond the JVM -  DDTX 2018
Big data beyond the JVM - DDTX 2018
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Yahoo is open to developers
Yahoo is open to developersYahoo is open to developers
Yahoo is open to developers
 
Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2
 
Supa fast Ruby + Rails
Supa fast Ruby + RailsSupa fast Ruby + Rails
Supa fast Ruby + Rails
 
Selenium&amp;scrapy
Selenium&amp;scrapySelenium&amp;scrapy
Selenium&amp;scrapy
 
Opening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the IslandsOpening up the Social Web - Standards that are bridging the Islands
Opening up the Social Web - Standards that are bridging the Islands
 
Socket applications
Socket applicationsSocket applications
Socket applications
 

Andere mochten auch

Diễn họa ( Sketch with water colour)
Diễn họa ( Sketch with water colour)Diễn họa ( Sketch with water colour)
Diễn họa ( Sketch with water colour)Le Hao
 
Proyec Aeroblade Bahia De Cadiz
Proyec Aeroblade Bahia De CadizProyec Aeroblade Bahia De Cadiz
Proyec Aeroblade Bahia De CadizAtonor
 
Global Ceramic Tiles Industry
Global Ceramic Tiles IndustryGlobal Ceramic Tiles Industry
Global Ceramic Tiles IndustryReportLinker.com
 
Topled Introduction
Topled IntroductionTopled Introduction
Topled Introductionmaconhang
 
Ylb planta móvil mezcladora de asfalto
Ylb planta móvil mezcladora de asfaltoYlb planta móvil mezcladora de asfalto
Ylb planta móvil mezcladora de asfaltojiang12707070
 
VYS Devon Youth News Local June 2010
VYS Devon Youth News Local June 2010VYS Devon Youth News Local June 2010
VYS Devon Youth News Local June 2010Diocese of Exeter
 
Caracterizacion parcial de peliculas preparadas con almidon oxidado de platano
Caracterizacion parcial de peliculas preparadas con almidon oxidado de platanoCaracterizacion parcial de peliculas preparadas con almidon oxidado de platano
Caracterizacion parcial de peliculas preparadas con almidon oxidado de platanoVisel Rodrigo Hancco
 
dmr's Moments Of Truth Conclave Webinar
dmr's Moments Of Truth Conclave Webinardmr's Moments Of Truth Conclave Webinar
dmr's Moments Of Truth Conclave Webinardmrinteractive
 
Pinterest. La guía definitiva
Pinterest. La guía definitivaPinterest. La guía definitiva
Pinterest. La guía definitivaOleoshop
 
Explicació teoria de l'evolució
Explicació teoria de l'evolucióExplicació teoria de l'evolució
Explicació teoria de l'evolucióesborn2003
 
Todo sobre la Web 2.0
Todo sobre la Web 2.0 Todo sobre la Web 2.0
Todo sobre la Web 2.0 PrettyCat1
 
01 PIAS y PAIS Carmen Echevarría
01 PIAS y PAIS Carmen Echevarría01 PIAS y PAIS Carmen Echevarría
01 PIAS y PAIS Carmen EchevarríaSAMFYRE
 
How To Engineer A Christmas Tree
How To Engineer A Christmas TreeHow To Engineer A Christmas Tree
How To Engineer A Christmas TreeMarissa Oskarsen
 
ELV companies in UAE
ELV companies in UAE ELV companies in UAE
ELV companies in UAE Data Zoneme
 
Introduction_to_FRACAS - Course_Outline
Introduction_to_FRACAS - Course_OutlineIntroduction_to_FRACAS - Course_Outline
Introduction_to_FRACAS - Course_OutlineBill Keeter
 

Andere mochten auch (20)

Diễn họa ( Sketch with water colour)
Diễn họa ( Sketch with water colour)Diễn họa ( Sketch with water colour)
Diễn họa ( Sketch with water colour)
 
Proyec Aeroblade Bahia De Cadiz
Proyec Aeroblade Bahia De CadizProyec Aeroblade Bahia De Cadiz
Proyec Aeroblade Bahia De Cadiz
 
Global Ceramic Tiles Industry
Global Ceramic Tiles IndustryGlobal Ceramic Tiles Industry
Global Ceramic Tiles Industry
 
Topled Introduction
Topled IntroductionTopled Introduction
Topled Introduction
 
Ylb planta móvil mezcladora de asfalto
Ylb planta móvil mezcladora de asfaltoYlb planta móvil mezcladora de asfalto
Ylb planta móvil mezcladora de asfalto
 
VYS Devon Youth News Local June 2010
VYS Devon Youth News Local June 2010VYS Devon Youth News Local June 2010
VYS Devon Youth News Local June 2010
 
Caracterizacion parcial de peliculas preparadas con almidon oxidado de platano
Caracterizacion parcial de peliculas preparadas con almidon oxidado de platanoCaracterizacion parcial de peliculas preparadas con almidon oxidado de platano
Caracterizacion parcial de peliculas preparadas con almidon oxidado de platano
 
dmr's Moments Of Truth Conclave Webinar
dmr's Moments Of Truth Conclave Webinardmr's Moments Of Truth Conclave Webinar
dmr's Moments Of Truth Conclave Webinar
 
Dc08 Joe Suh
Dc08   Joe SuhDc08   Joe Suh
Dc08 Joe Suh
 
Pinterest. La guía definitiva
Pinterest. La guía definitivaPinterest. La guía definitiva
Pinterest. La guía definitiva
 
Explicació teoria de l'evolució
Explicació teoria de l'evolucióExplicació teoria de l'evolució
Explicació teoria de l'evolució
 
Fast track
Fast trackFast track
Fast track
 
Todo sobre la Web 2.0
Todo sobre la Web 2.0 Todo sobre la Web 2.0
Todo sobre la Web 2.0
 
01 PIAS y PAIS Carmen Echevarría
01 PIAS y PAIS Carmen Echevarría01 PIAS y PAIS Carmen Echevarría
01 PIAS y PAIS Carmen Echevarría
 
How To Engineer A Christmas Tree
How To Engineer A Christmas TreeHow To Engineer A Christmas Tree
How To Engineer A Christmas Tree
 
ELV companies in UAE
ELV companies in UAE ELV companies in UAE
ELV companies in UAE
 
Catalogo campaña 2 enero-20-2015
Catalogo campaña 2 enero-20-2015Catalogo campaña 2 enero-20-2015
Catalogo campaña 2 enero-20-2015
 
Saleme roseliane danzas
Saleme roseliane danzasSaleme roseliane danzas
Saleme roseliane danzas
 
Guion de blade runner
Guion de blade runnerGuion de blade runner
Guion de blade runner
 
Introduction_to_FRACAS - Course_Outline
Introduction_to_FRACAS - Course_OutlineIntroduction_to_FRACAS - Course_Outline
Introduction_to_FRACAS - Course_Outline
 

Ähnlich wie Stop Reinventing The Wheel - The Ruby Standard Library

Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareAlona Mekhovova
 
Digital Library Federation, Fall 07, Connotea Presentation
Digital Library Federation, Fall 07, Connotea PresentationDigital Library Federation, Fall 07, Connotea Presentation
Digital Library Federation, Fall 07, Connotea PresentationIan Mulvany
 
Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...
Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...
Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...ruyalarcon
 
REST teori og praksis; REST in theory and practice
REST teori og praksis; REST in theory and practiceREST teori og praksis; REST in theory and practice
REST teori og praksis; REST in theory and practicehamnis
 
Puppet getting started by Dirk Götz
Puppet getting started by Dirk GötzPuppet getting started by Dirk Götz
Puppet getting started by Dirk GötzNETWAYS
 
Extreme APIs for a better tomorrow
Extreme APIs for a better tomorrowExtreme APIs for a better tomorrow
Extreme APIs for a better tomorrowAaron Maturen
 
Exploiter le Web Semantic, le comprendre et y contribuer
Exploiter le Web Semantic, le comprendre et y contribuerExploiter le Web Semantic, le comprendre et y contribuer
Exploiter le Web Semantic, le comprendre et y contribuerMathieu d'Aquin
 
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스Node.js 기반 정적 페이지 블로그 엔진, 하루프레스
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스Rhio Kim
 
How to connect social media with open standards
How to connect social media with open standardsHow to connect social media with open standards
How to connect social media with open standardsGlenn Jones
 
How I built the demo's
How I built the demo'sHow I built the demo's
How I built the demo'sGlenn Jones
 
Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...
Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...
Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...rhatr
 
Web backends development using Python
Web backends development using PythonWeb backends development using Python
Web backends development using PythonAyun Park
 
REST Introduction (PHP London)
REST Introduction (PHP London)REST Introduction (PHP London)
REST Introduction (PHP London)Paul James
 
Motion Django Meetup
Motion Django MeetupMotion Django Meetup
Motion Django MeetupMike Malone
 
Python & Django TTT
Python & Django TTTPython & Django TTT
Python & Django TTTkevinvw
 
WordCamp Bournemouth 2014 - Designing with data in WordPress
WordCamp Bournemouth 2014 - Designing with data in WordPressWordCamp Bournemouth 2014 - Designing with data in WordPress
WordCamp Bournemouth 2014 - Designing with data in WordPressJonny Allbut
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Baruch Sadogursky
 
How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.DrupalCampDN
 
Puppet at Pinterest
Puppet at PinterestPuppet at Pinterest
Puppet at PinterestPuppet
 

Ähnlich wie Stop Reinventing The Wheel - The Ruby Standard Library (20)

Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 
Sprockets
SprocketsSprockets
Sprockets
 
Digital Library Federation, Fall 07, Connotea Presentation
Digital Library Federation, Fall 07, Connotea PresentationDigital Library Federation, Fall 07, Connotea Presentation
Digital Library Federation, Fall 07, Connotea Presentation
 
Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...
Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...
Fulfilling the Hypermedia Constraint via HTTP OPTIONS, The HTTP Vocabulary In...
 
REST teori og praksis; REST in theory and practice
REST teori og praksis; REST in theory and practiceREST teori og praksis; REST in theory and practice
REST teori og praksis; REST in theory and practice
 
Puppet getting started by Dirk Götz
Puppet getting started by Dirk GötzPuppet getting started by Dirk Götz
Puppet getting started by Dirk Götz
 
Extreme APIs for a better tomorrow
Extreme APIs for a better tomorrowExtreme APIs for a better tomorrow
Extreme APIs for a better tomorrow
 
Exploiter le Web Semantic, le comprendre et y contribuer
Exploiter le Web Semantic, le comprendre et y contribuerExploiter le Web Semantic, le comprendre et y contribuer
Exploiter le Web Semantic, le comprendre et y contribuer
 
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스Node.js 기반 정적 페이지 블로그 엔진, 하루프레스
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스
 
How to connect social media with open standards
How to connect social media with open standardsHow to connect social media with open standards
How to connect social media with open standards
 
How I built the demo's
How I built the demo'sHow I built the demo's
How I built the demo's
 
Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...
Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...
Building Google-in-a-box: using Apache SolrCloud and Bigtop to index your big...
 
Web backends development using Python
Web backends development using PythonWeb backends development using Python
Web backends development using Python
 
REST Introduction (PHP London)
REST Introduction (PHP London)REST Introduction (PHP London)
REST Introduction (PHP London)
 
Motion Django Meetup
Motion Django MeetupMotion Django Meetup
Motion Django Meetup
 
Python & Django TTT
Python & Django TTTPython & Django TTT
Python & Django TTT
 
WordCamp Bournemouth 2014 - Designing with data in WordPress
WordCamp Bournemouth 2014 - Designing with data in WordPressWordCamp Bournemouth 2014 - Designing with data in WordPress
WordCamp Bournemouth 2014 - Designing with data in WordPress
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java
 
How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.How to? Drupal developer toolkit. Dennis Povshedny.
How to? Drupal developer toolkit. Dennis Povshedny.
 
Puppet at Pinterest
Puppet at PinterestPuppet at Pinterest
Puppet at Pinterest
 

Mehr von Brian Hogan

Creating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoCreating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoBrian Hogan
 
Automating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and AnsibleAutomating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and AnsibleBrian Hogan
 
Create Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantCreate Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantBrian Hogan
 
Getting Started Contributing To Open Source
Getting Started Contributing To Open SourceGetting Started Contributing To Open Source
Getting Started Contributing To Open SourceBrian Hogan
 
Rethink Frontend Development With Elm
Rethink Frontend Development With ElmRethink Frontend Development With Elm
Rethink Frontend Development With ElmBrian Hogan
 
Testing Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScriptTesting Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScriptBrian Hogan
 
FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.Brian Hogan
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web DesignBrian Hogan
 
Turning Passion Into Words
Turning Passion Into WordsTurning Passion Into Words
Turning Passion Into WordsBrian Hogan
 
HTML5 and CSS3 Today
HTML5 and CSS3 TodayHTML5 and CSS3 Today
HTML5 and CSS3 TodayBrian Hogan
 
Web Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To ComplexWeb Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To ComplexBrian Hogan
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Brian Hogan
 
Make GUI Apps with Shoes
Make GUI Apps with ShoesMake GUI Apps with Shoes
Make GUI Apps with ShoesBrian Hogan
 
Story-driven Testing
Story-driven TestingStory-driven Testing
Story-driven TestingBrian Hogan
 
Learning To Walk In Shoes
Learning To Walk In ShoesLearning To Walk In Shoes
Learning To Walk In ShoesBrian Hogan
 
Rails and Legacy Databases - RailsConf 2009
Rails and Legacy Databases - RailsConf 2009Rails and Legacy Databases - RailsConf 2009
Rails and Legacy Databases - RailsConf 2009Brian Hogan
 

Mehr von Brian Hogan (19)

Creating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoCreating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with Hugo
 
Automating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and AnsibleAutomating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and Ansible
 
Create Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantCreate Development and Production Environments with Vagrant
Create Development and Production Environments with Vagrant
 
Docker
DockerDocker
Docker
 
Getting Started Contributing To Open Source
Getting Started Contributing To Open SourceGetting Started Contributing To Open Source
Getting Started Contributing To Open Source
 
Rethink Frontend Development With Elm
Rethink Frontend Development With ElmRethink Frontend Development With Elm
Rethink Frontend Development With Elm
 
Testing Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScriptTesting Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScript
 
FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web Design
 
Turning Passion Into Words
Turning Passion Into WordsTurning Passion Into Words
Turning Passion Into Words
 
HTML5 and CSS3 Today
HTML5 and CSS3 TodayHTML5 and CSS3 Today
HTML5 and CSS3 Today
 
Web Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To ComplexWeb Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To Complex
 
Intro to Ruby
Intro to RubyIntro to Ruby
Intro to Ruby
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 
Make GUI Apps with Shoes
Make GUI Apps with ShoesMake GUI Apps with Shoes
Make GUI Apps with Shoes
 
The Why Of Ruby
The Why Of RubyThe Why Of Ruby
The Why Of Ruby
 
Story-driven Testing
Story-driven TestingStory-driven Testing
Story-driven Testing
 
Learning To Walk In Shoes
Learning To Walk In ShoesLearning To Walk In Shoes
Learning To Walk In Shoes
 
Rails and Legacy Databases - RailsConf 2009
Rails and Legacy Databases - RailsConf 2009Rails and Legacy Databases - RailsConf 2009
Rails and Legacy Databases - RailsConf 2009
 

Kürzlich hochgeladen

Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 

Kürzlich hochgeladen (20)

Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 

Stop Reinventing The Wheel - The Ruby Standard Library

  • 1. stop reinventing the wheel hidden gems in the ruby standard library brian hogan - @bphogan
  • 3. What about this design? describe "the user" do it "gets an email when their account is activated" do # some stuff end end Twitter: @bphogan Web: http://www.napcs.com/
  • 4. Sometimes ideas evolve for the better. Twitter: @bphogan Web: http://www.napcs.com/
  • 5. Other times not so much. Twitter: @bphogan Web: http://www.napcs.com/
  • 6. In software we reinvent Twitter: @bphogan Web: http://www.napcs.com/
  • 7. How often is “better” really just opinion? Twitter: @bphogan Web: http://www.napcs.com/
  • 8. So, we’re not talking about always using what exists... Twitter: @bphogan Web: http://www.napcs.com/
  • 9. We’re talking about reinventing because of ignorance, hubris, or ego. Twitter: @bphogan Web: http://www.napcs.com/
  • 10. Ruby Standard Library http://ruby-doc.org/stdlib/ Twitter: @bphogan Web: http://www.napcs.com/
  • 11. •FileUtils •Forwardable •Pathname •open-uri •TempFile •WEBrick Twitter: @bphogan Web: http://www.napcs.com/
  • 12. Working With The File System system("mkdir -p tmp/files") system("touch tmp/files/lockfile.lock") system("rm -rf tmp/files") Twitter: @bphogan Web: http://www.napcs.com/
  • 13. Make it platform- independent! require 'fileutils' FileUtils.mkdir_p("tmp/files") FileUtils.touch("tmp/files/lockfile.lock") FileUtils.rm_rf("tmp/files") Twitter: @bphogan Web: http://www.napcs.com/
  • 14. FileUtils Namespace for several file utility methods for copying, moving, removing, etc. Twitter: @bphogan Web: http://www.napcs.com/
  • 15. Where it’s used •Rake •Capistrano stuff •Sinatra Reloader gem •Compass Twitter: @bphogan Web: http://www.napcs.com/
  • 16. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 17. Delegating Methods Calling methods on one class through another. User Profile name name Twitter: @bphogan Web: http://www.napcs.com/
  • 18. Here’s how Rails does it def delegate(*methods) options = methods.pop unless options.is_a?(Hash) && to = options[:to] raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)." end methods.each do |method| module_eval("def #{method}(*args, &block) n#{to}.__send__(#{method.inspect}, *args, &block)nendn", "(__DELEGATION__)", 1) end end Twitter: @bphogan Web: http://www.napcs.com/
  • 19. Here’s how Rails does it class User < ActiveRecord::Base has_one :profile delegate :name, :to => :profile end Twitter: @bphogan Web: http://www.napcs.com/
  • 20. Here’s how we could do it. require 'forwardable' class User < ActiveRecord::Base has_one :profile extend Forwardable def_delegator :profile, :bio, :bio end Twitter: @bphogan Web: http://www.napcs.com/
  • 21. Forwardable This library allows you delegate method calls to an object, on a method by method basis. Twitter: @bphogan Web: http://www.napcs.com/
  • 22. Where it’s used •MongoMapper •Rack::Client Twitter: @bphogan Web: http://www.napcs.com/
  • 23. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 24. Working with Paths Twitter: @bphogan Web: http://www.napcs.com/
  • 25. Seen in tons of Rails apps... file = File.join(RAILS_ROOT, "config", "database.yml") config = YAML.load(File.read(file)) Twitter: @bphogan Web: http://www.napcs.com/
  • 26. A better way file = Rails.root.join("config", "database.yml") config = YAML.load(file.read) Rails.root.class => Pathname http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/ Twitter: @bphogan Web: http://www.napcs.com/
  • 27. Pathname Library to simplify working with files and paths. Represents a pathname which locates a file in a filesystem. The pathname depends on OS: Unix, Windows, etc. Twitter: @bphogan Web: http://www.napcs.com/
  • 28. Neat stuff require 'pathname' p = Pathname.new("/usr/bin/ruby") size = p.size # 27662 isdir = p.directory? # false dir = p.dirname # Pathname:/usr/bin base = p.basename # Pathname:ruby dir, base = p.split # [Pathname:/usr/bin, Pathname:ruby] Twitter: @bphogan Web: http://www.napcs.com/
  • 29. Where it’s used •Rails •DataMapper •Warehouse •Webistrano •many many more Twitter: @bphogan Web: http://www.napcs.com/
  • 30. Grabbing Files Twitter: @bphogan Web: http://www.napcs.com/
  • 31. cURL? puts `curl http://pastie.org/1131498.txt? key=zst64zkddsxafra0jz678g` Twitter: @bphogan Web: http://www.napcs.com/
  • 32. Not available everywhere, must handle redirects. Twitter: @bphogan Web: http://www.napcs.com/
  • 33. Treat URLs as files! require 'open-uri' url = "http://pastie.org/1131498.txt?key=zst64zkddsxafra0jz678g" puts open(url).read Twitter: @bphogan Web: http://www.napcs.com/
  • 34. open-uri Wraps net/http, net/https, and net/ftp. Twitter: @bphogan Web: http://www.napcs.com/
  • 35. Where it’s used •Everywhere. Twitter: @bphogan Web: http://www.napcs.com/
  • 36. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 38. The hard way path = "http://pastie.org/1131498.txt?key=zst64zkddsxafra0jz678g" `curl #{path} > /tmp/template.html` s = File.read("/tmp/template.html") puts s Twitter: @bphogan Web: http://www.napcs.com/
  • 39. Use TempFile require 'open-uri' require 'tempfile' url = "http://pastie.org/1131498.txt?key=zst64zkddsxafra0jz678g" tempfile = Tempfile.new("template.html") tempfile.write open(url).read puts tempfile.open.read Twitter: @bphogan Web: http://www.napcs.com/
  • 40. Where it’s used •File uploading •Caching Twitter: @bphogan Web: http://www.napcs.com/
  • 41. Data structures Twitter: @bphogan Web: http://www.napcs.com/
  • 42. YAML loads to hashes require 'YAML' config = YAML.load(Pathname.new("config.yml").read) puts config["company_name"] puts config["banner_image_url"] puts config["custom_css_url"] Twitter: @bphogan Web: http://www.napcs.com/
  • 43. Use OpenStruct! require 'ostruct' require 'YAML' config = YAML.load(Pathname.new("config.yml").read) config = OpenStruct.new(config) puts config.company_name puts config.banner_image_url puts config.custom_css_url Twitter: @bphogan Web: http://www.napcs.com/
  • 44. Don’t write your own “YAML-to-Object” thing (like I once did!) Twitter: @bphogan Web: http://www.napcs.com/
  • 45. Where it’s used •Fat Free CMS •ActiveMessaging •Adhearsion •AASM Twitter: @bphogan Web: http://www.napcs.com/
  • 46. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 47. Watching Stuff Twitter: @bphogan Web: http://www.napcs.com/
  • 49. def initialize super observed_descendants.each { |klass| add_observer!(klass) } end def self.method_added(method) method = method.to_sym if ActiveRecord::Callbacks::CALLBACKS.include?(method) self.observed_methods += [method] self.observed_methods.freeze end end protected def observed_descendants observed_classes.sum([]) { |klass| klass.descendants } end def observe_callbacks? self.class.observed_methods.any? end def add_observer!(klass) super define_callbacks klass if observe_callbacks? end def define_callbacks(klass) existing_methods = klass.instance_methods.map { |m| m.to_sym } observer = self observer_name = observer.class.name.underscore.gsub('/', '__') self.class.observed_methods.each do |method| callback = :"_notify_#{observer_name}_for_#{method}" unless existing_methods.include? callback klass.send(:define_method, callback) do # def _notify_user_observer_for_before_save observer.update(method, self) # observer.update(:before_save, self) end # end klass.send(method, callback) # before_save :_notify_user_observer_for_before_save end end end end end Twitter: @bphogan Web: http://www.napcs.com/
  • 50. Observer Provides a simple mechanism for one object to inform a set of interested third-party objects when its state changes. Twitter: @bphogan Web: http://www.napcs.com/
  • 51. How we do it require 'observer' class ConfirmationEmailer def update(account) puts "Sending confirmation mail to: '#{account.email}'" # send the email mechanism end end Twitter: @bphogan Web: http://www.napcs.com/
  • 52. class Account include Observable attr_accessor :email, :active def initialize(email) self.email = email self.active = false add_observer ConfirmationEmailer.new end def activate_account! self.active = true changed # <- This is important notify_observers self end end Twitter: @bphogan Web: http://www.napcs.com/
  • 53. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 54. Serving Web Pages Twitter: @bphogan Web: http://www.napcs.com/
  • 55. Sinatra? require 'sinatra' set :public, "~/Sites" Twitter: @bphogan Web: http://www.napcs.com/
  • 56. How about this? s = WEBrick::HTTPServer.new(:Port => 3000, :DocumentRoot => "~/Sites") trap('INT') { s.shutdown }; s.start Twitter: @bphogan Web: http://www.napcs.com/
  • 57. How about an alias? alias serve="ruby -rwebrick -e"s = WEBrick::HTTPServer.new(:Port => 3000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start"" $ cd ~/Sites $ serve Twitter: @bphogan Web: http://www.napcs.com/
  • 59. It also serves web apps Twitter: @bphogan Web: http://www.napcs.com/
  • 60. Your dev machine really needs Passenger running? Twitter: @bphogan Web: http://www.napcs.com/
  • 61. Where it’s used •Rails •Other frameworks Twitter: @bphogan Web: http://www.napcs.com/
  • 62. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 63. Storing Data Twitter: @bphogan Web: http://www.napcs.com/
  • 64. PStore Persistent, transactional storage. Baked right in to Ruby’s standard library. Twitter: @bphogan Web: http://www.napcs.com/
  • 65. We can store stuff... require 'pstore' store = PStore.new('links') links = %W{http://www.github.com http://heroku.com http://ruby-lang.org} store.transaction do store[:links] ||= [] links.each{|link| store[:links] << link} store[:last_modified] = Time.now end Twitter: @bphogan Web: http://www.napcs.com/
  • 66. and we can get it back. store = PStore.new("links") store.transaction do links = store[:links] end puts links.join("n") Twitter: @bphogan Web: http://www.napcs.com/
  • 67. Where it’s used •Rails 1.x Twitter: @bphogan Web: http://www.napcs.com/
  • 68. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 69. Better Wheels Twitter: @bphogan Web: http://www.napcs.com/
  • 70. Importing CSV files require 'csv' CSV.open('data.csv', 'r', ';') do |row| p row end Twitter: @bphogan Web: http://www.napcs.com/
  • 71. CSV is slow. “Use FasterCSV” Twitter: @bphogan Web: http://www.napcs.com/
  • 72. In Ruby 1.9, FasterCSV is the new CSV! Twitter: @bphogan Web: http://www.napcs.com/
  • 73. Working with Dates Twitter: @bphogan Web: http://www.napcs.com/
  • 74. How we do it today = DateTime.now birthday = Date.new(2010, 10, 5) days_to_go = birthday - today time_until = birthday - today hours,minutes,seconds,frac = Date.day_fraction_to_time(time_until) http://www.techotopia.com/index.php/Working_with_Dates_and_Times_in_Ruby Twitter: @bphogan Web: http://www.napcs.com/
  • 75. home_run home_run is an implementation of rubyʼs Date/ DateTime classes in C, with much better performance (20-200x) than the version in the standard library, while being almost completely compatible. http://github.com/jeremyevans/home_run Twitter: @bphogan Web: http://www.napcs.com/
  • 76. REXML Built-in library for parsing and creating XML. Twitter: @bphogan Web: http://www.napcs.com/
  • 77. How about HPricot, libxml- ruby, or Nokogiri. http://www.rubyinside.com/ruby-xml-performance-benchmarks-1641.html Twitter: @bphogan Web: http://www.napcs.com/
  • 78. ERb Templating language as part of the Standard Library. Twitter: @bphogan Web: http://www.napcs.com/
  • 79. require 'erb' template = ERB.new <<-EOF <h1><%=@name %></h1> EOF @name = "AwesomeCo" puts template.result Twitter: @bphogan Web: http://www.napcs.com/
  • 80. Templating language != View language!!! Twitter: @bphogan Web: http://www.napcs.com/
  • 81. What can it do? •Generate JavaScript •Generate YAML •Generate ERb •Any type of proprietary data export Twitter: @bphogan Web: http://www.napcs.com/
  • 82. Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  • 83. Alternatives? •HAML •Liquid •ERubis •Tons of others Twitter: @bphogan Web: http://www.napcs.com/
  • 84. Test::Unit We have an awesome testing library as part of our standard library. Twitter: @bphogan Web: http://www.napcs.com/
  • 85. It’s pretty good. Anyone know of any alternatives? Twitter: @bphogan Web: http://www.napcs.com/
  • 86. Only a few. •RSpec •Bacon •Context / Contest / Shoulda / Matchy •Testy •Micronaut •Whatever someone writes next week Twitter: @bphogan Web: http://www.napcs.com/
  • 87. I use RSpec * * And I still use Test::Unit. Twitter: @bphogan Web: http://www.napcs.com/
  • 88. “Minitest is a minitest/unit is a small and fast replacement for ruby's huge and slow test/unit”. Twitter: @bphogan Web: http://www.napcs.com/
  • 89. If X sucks so bad, why do we write something else instead of fixing it? Twitter: @bphogan Web: http://www.napcs.com/
  • 90. We think we can do it better. Twitter: @bphogan Web: http://www.napcs.com/
  • 91. The original developer doesn’t want our help. Twitter: @bphogan Web: http://www.napcs.com/
  • 92. There’s a language barrier. Twitter: @bphogan Web: http://www.napcs.com/
  • 93. Challenge: Extend the Standard Library. Twitter: @bphogan Web: http://www.napcs.com/
  • 94. Make the wheels we have better. Twitter: @bphogan Web: http://www.napcs.com/
  • 95. That’s it. •Twitter: @bphogan •email: bphogan@gmail.com •web: http://www.napcs.com/ •blog: http://bphogan.com •github: http://github.com/napcs/ Twitter: @bphogan Web: http://www.napcs.com/