Uploaded byBrian Hogan · Slideshare

Brian Hogan discusses the Ruby standard library, highlighting its valuable features and the pitfalls of reinventing existing solutions due to ignorance or ego. He explores various libraries such as FileUtils, Forwardable, and OpenURI while emphasizing the importance of leveraging existing tools to improve efficiency in software development. Ultimately, he encourages developers to extend and enhance the standard library instead of creating new alternatives.

Download as KEY, PPTX

  1. 1 / 95
  2. 2 / 95
  3. 3 / 95
  4. 4 / 95
  5. 5 / 95
  6. 6 / 95
  7. 7 / 95
  8. 8 / 95
  9. 9 / 95
  10. 10 / 95
  11. 11 / 95
  12. 12 / 95
  13. 13 / 95
  14. 14 / 95
  15. 15 / 95
  16. 16 / 95
  17. 17 / 95
  18. 18 / 95
  19. 19 / 95
  20. 20 / 95
  21. 21 / 95
  22. 22 / 95
  23. 23 / 95
  24. 24 / 95
  25. 25 / 95
  26. 26 / 95
  27. 27 / 95
  28. 28 / 95
  29. 29 / 95
  30. 30 / 95
  31. 31 / 95
  32. 32 / 95
  33. 33 / 95
  34. 34 / 95
  35. 35 / 95
  36. 36 / 95
  37. 37 / 95
  38. 38 / 95
  39. 39 / 95
  40. 40 / 95
  41. 41 / 95
  42. 42 / 95
  43. 43 / 95
  44. 44 / 95
  45. 45 / 95
  46. 46 / 95
  47. 47 / 95
  48. 48 / 95
  49. 49 / 95
  50. 50 / 95
  51. 51 / 95
  52. 52 / 95
  53. 53 / 95
  54. 54 / 95
  55. 55 / 95
  56. 56 / 95
  57. 57 / 95
  58. 58 / 95
  59. 59 / 95
  60. 60 / 95
  61. 61 / 95
  62. 62 / 95
  63. 63 / 95
  64. 64 / 95
  65. 65 / 95
  66. 66 / 95
  67. 67 / 95
  68. 68 / 95
  69. 69 / 95
  70. 70 / 95
  71. 71 / 95
  72. 72 / 95
  73. 73 / 95
  74. 74 / 95
  75. 75 / 95
  76. 76 / 95
  77. 77 / 95
  78. 78 / 95
  79. 79 / 95
  80. 80 / 95
  81. 81 / 95
  82. 82 / 95
  83. 83 / 95
  84. 84 / 95
  85. 85 / 95
  86. 86 / 95
  87. 87 / 95
  88. 88 / 95
  89. 89 / 95
  90. 90 / 95
  91. 91 / 95
  92. 92 / 95
  93. 93 / 95
  94. 94 / 95
  95. 95 / 95
  1. stop reinventing
    the wheel
hidden gems in the ruby standard library
      brian hogan - @bphogan

    Download now

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

    Download now

  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/

    Download now

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

    Download now

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

    Download now

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

    Download now

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

    Download now

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

    Download now

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

    Download now

  10. Ruby Standard Library
                             http://ruby-doc.org/stdlib/
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

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

    Download now

  15. Where it’s used
           •Rake
           •Capistrano stuff
           •Sinatra Reloader gem
           •Compass
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

  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/

    Download now

  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/

    Download now

  22. Where it’s used
           •MongoMapper
           •Rack::Client
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

  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/

    Download now

  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/

    Download now

  29. Where it’s used
           •Rails
           •DataMapper
           •Warehouse
           •Webistrano
           •many many more
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

  30. Grabbing Files
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  34. open-uri
                 Wraps net/http, net/https, and net/ftp.
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

  40. Where it’s used
           •File uploading
           •Caching
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

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

    Download now

  45. Where it’s used
           •Fat Free CMS
           •ActiveMessaging
           •Adhearsion
           •AASM
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

  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/

    Download now

  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/

    Download now

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

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

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

    Download now

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

    Download now

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

    Download now

  61. Where it’s used
           •Rails
           •Other frameworks
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

  67. Where it’s used
           •Rails 1.x
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

  70. Importing CSV files
     require 'csv'
       CSV.open('data.csv', 'r', ';') do |row|
         p row
       end
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

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

    Download now

  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/

    Download now

  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/

    Download now

  76. REXML
            Built-in library for
        parsing and creating XML.
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

  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/

    Download now

  78. ERb
      Templating language as part of the Standard Library.
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

  79. require 'erb'
                        template = ERB.new <<-EOF
                         <h1><%=@name %></h1>
                        EOF
                        @name = "AwesomeCo"
                        puts template.result
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

  81. What can it do?
           •Generate JavaScript
           •Generate YAML
           •Generate ERb
           •Any type of proprietary data export
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

  83. Alternatives?
           •HAML
           •Liquid
           •ERubis
           •Tons of others
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

  84. Test::Unit
                 We have an awesome testing library
                   as part of our standard library.
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

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

    Download now

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

    Download now

  87. I use RSpec *
                             * And I still use Test::Unit.
Twitter: @bphogan
Web: http://www.napcs.com/

    Download now

  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/

    Download now

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

    Download now

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

    Download now

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

    Download now

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

    Download now

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

    Download now

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

    Download now

  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/

    Download now

Stop Reinventing The Wheel - The Ruby Standard Library

  1. 1.stop reinventing the wheel hidden gems in the ruby standard library brian hogan - @bphogan
  2. 2.Twitter: @bphogan Web: http://www.napcs.com/
  3. 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. 4.Sometimes ideas evolve for the better. Twitter: @bphogan Web: http://www.napcs.com/
  5. 5.Other times not so much. Twitter: @bphogan Web: http://www.napcs.com/
  6. 6.In software we reinvent Twitter: @bphogan Web: http://www.napcs.com/
  7. 7.How often is “better” really just opinion? Twitter: @bphogan Web: http://www.napcs.com/
  8. 8.So, we’re not talking about always using what exists... Twitter: @bphogan Web: http://www.napcs.com/
  9. 9.We’re talking about reinventing because of ignorance, hubris, or ego. Twitter: @bphogan Web: http://www.napcs.com/
  10. 10.Ruby Standard Library http://ruby-doc.org/stdlib/ Twitter: @bphogan Web: http://www.napcs.com/
  11. 11.•FileUtils •Forwardable •Pathname •open-uri •TempFile •WEBrick Twitter: @bphogan Web: http://www.napcs.com/
  12. 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. 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. 14.FileUtils Namespace for several file utility methods for copying, moving, removing, etc. Twitter: @bphogan Web: http://www.napcs.com/
  15. 15.Where it’s used •Rake •Capistrano stuff •Sinatra Reloader gem •Compass Twitter: @bphogan Web: http://www.napcs.com/
  16. 16.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  17. 17.Delegating Methods Calling methods on one class through another. User Profile name name Twitter: @bphogan Web: http://www.napcs.com/
  18. 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. 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. 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. 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. 22.Where it’s used •MongoMapper •Rack::Client Twitter: @bphogan Web: http://www.napcs.com/
  23. 23.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  24. 24.Working with Paths Twitter: @bphogan Web: http://www.napcs.com/
  25. 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. 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. 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. 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. 29.Where it’s used •Rails •DataMapper •Warehouse •Webistrano •many many more Twitter: @bphogan Web: http://www.napcs.com/
  30. 30.Grabbing Files Twitter: @bphogan Web: http://www.napcs.com/
  31. 31.cURL? puts `curl http://pastie.org/1131498.txt? key=zst64zkddsxafra0jz678g` Twitter: @bphogan Web: http://www.napcs.com/
  32. 32.Not available everywhere, must handle redirects. Twitter: @bphogan Web: http://www.napcs.com/
  33. 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. 34.open-uri Wraps net/http, net/https, and net/ftp. Twitter: @bphogan Web: http://www.napcs.com/
  35. 35.Where it’s used •Everywhere. Twitter: @bphogan Web: http://www.napcs.com/
  36. 36.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  37. 37.Temporary files Twitter: @bphogan Web: http://www.napcs.com/
  38. 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. 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. 40.Where it’s used •File uploading •Caching Twitter: @bphogan Web: http://www.napcs.com/
  41. 41.Data structures Twitter: @bphogan Web: http://www.napcs.com/
  42. 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. 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. 44.Don’t write your own “YAML-to-Object” thing (like I once did!) Twitter: @bphogan Web: http://www.napcs.com/
  45. 45.Where it’s used •Fat Free CMS •ActiveMessaging •Adhearsion •AASM Twitter: @bphogan Web: http://www.napcs.com/
  46. 46.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  47. 47.Watching Stuff Twitter: @bphogan Web: http://www.napcs.com/
  48. 48.Rails? Twitter: @bphogan Web: http://www.napcs.com/
  49. 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. 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. 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. 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. 53.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  54. 54.Serving Web Pages Twitter: @bphogan Web: http://www.napcs.com/
  55. 55.Sinatra? require 'sinatra' set :public, "~/Sites" Twitter: @bphogan Web: http://www.napcs.com/
  56. 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. 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/
  58. 58.Twitter: @bphogan Web: http://www.napcs.com/
  59. 59.It also serves web apps Twitter: @bphogan Web: http://www.napcs.com/
  60. 60.Your dev machine really needs Passenger running? Twitter: @bphogan Web: http://www.napcs.com/
  61. 61.Where it’s used •Rails •Other frameworks Twitter: @bphogan Web: http://www.napcs.com/
  62. 62.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  63. 63.Storing Data Twitter: @bphogan Web: http://www.napcs.com/
  64. 64.PStore Persistent, transactional storage. Baked right in to Ruby’s standard library. Twitter: @bphogan Web: http://www.napcs.com/
  65. 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. 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. 67.Where it’s used •Rails 1.x Twitter: @bphogan Web: http://www.napcs.com/
  68. 68.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  69. 69.Better Wheels Twitter: @bphogan Web: http://www.napcs.com/
  70. 70.Importing CSV files require 'csv' CSV.open('data.csv', 'r', ';') do |row| p row end Twitter: @bphogan Web: http://www.napcs.com/
  71. 71.CSV is slow. “Use FasterCSV” Twitter: @bphogan Web: http://www.napcs.com/
  72. 72.In Ruby 1.9, FasterCSV is the new CSV! Twitter: @bphogan Web: http://www.napcs.com/
  73. 73.Working with Dates Twitter: @bphogan Web: http://www.napcs.com/
  74. 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. 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. 76.REXML Built-in library for parsing and creating XML. Twitter: @bphogan Web: http://www.napcs.com/
  77. 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. 78.ERb Templating language as part of the Standard Library. Twitter: @bphogan Web: http://www.napcs.com/
  79. 79.require 'erb' template = ERB.new <<-EOF <h1><%=@name %></h1> EOF @name = "AwesomeCo" puts template.result Twitter: @bphogan Web: http://www.napcs.com/
  80. 80.Templating language != View language!!! Twitter: @bphogan Web: http://www.napcs.com/
  81. 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. 82.Where does it fall short? Twitter: @bphogan Web: http://www.napcs.com/
  83. 83.Alternatives? •HAML •Liquid •ERubis •Tons of others Twitter: @bphogan Web: http://www.napcs.com/
  84. 84.Test::Unit We have an awesome testing library as part of our standard library. Twitter: @bphogan Web: http://www.napcs.com/
  85. 85.It’s pretty good. Anyone know of any alternatives? Twitter: @bphogan Web: http://www.napcs.com/
  86. 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. 87.I use RSpec * * And I still use Test::Unit. Twitter: @bphogan Web: http://www.napcs.com/
  88. 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. 89.If X sucks so bad, why do we write something else instead of fixing it? Twitter: @bphogan Web: http://www.napcs.com/
  90. 90.We think we can do it better. Twitter: @bphogan Web: http://www.napcs.com/
  91. 91.The original developer doesn’t want our help. Twitter: @bphogan Web: http://www.napcs.com/
  92. 92.There’s a language barrier. Twitter: @bphogan Web: http://www.napcs.com/
  93. 93.Challenge: Extend the Standard Library. Twitter: @bphogan Web: http://www.napcs.com/
  94. 94.Make the wheels we have better. Twitter: @bphogan Web: http://www.napcs.com/
  95. 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/

Read the original on slideshare.net ↗