SlideShare uma empresa Scribd logo
1 de 43
Building A Gem From
                     Scratch
                                 Madison Ruby, 2011




twitter: bphogan
email: brianhogan at napcs.com
What's A Gem?



twitter: bphogan
email: brianhogan at napcs.com
The (normal) Process
           • Come up with an idea
           • write some code
           • Release a gem
           • Beg people to write tests for you

twitter: bphogan
email: brianhogan at napcs.com
Our process

           • Come up with an idea and write some code
           • Throw all that code away
           • Rewrite it with tests as we go
           • Release it as a Gem
           • Enjoy fame and fortune
twitter: bphogan
email: brianhogan at napcs.com
Grabatar
                        (a gem to grab Gravatar URLs)

                     http://www.gravatar.com/avatar/
                   6ef8cb7cd7cd58077f0b57e4fa49a969




twitter: bphogan
email: brianhogan at napcs.com
Step one: Build tested,
                 working code


twitter: bphogan
email: brianhogan at napcs.com
The basic structure of a
                   Gem
                                 gemname.gemspec
                                 lib/
                                        gemname
                                           version.rb
                                           anotherfile.rb
                                        gemname.rb

twitter: bphogan
email: brianhogan at napcs.com
Tests, Tests, Tests!




twitter: bphogan
email: brianhogan at napcs.com
Test::Unit
                                   test
                                          somefile_test.rb



twitter: bphogan
email: brianhogan at napcs.com
Write the test
   test/grabatar_test.rb

     require 'test/unit'
     require 'lib/grabatar'

     class GrabatarTest < Test::Unit::TestCase
       def test_displays_version
         assert Grabatar::VERSION
       end
     end




twitter: bphogan
email: brianhogan at napcs.com
Implement the code

   lib/grabatar/version.rb

      module Grabatar
        VERSION = "0.0.2"
      end




twitter: bphogan
email: brianhogan at napcs.com
Add to the main Ruby file:
   lib/grabatar.rb


     require 'grabatar/version'




twitter: bphogan
email: brianhogan at napcs.com
Repeat.



twitter: bphogan
email: brianhogan at napcs.com
Write the test first...
   test/gravatar_helper.rb

     require 'test/unit'
     require 'grabatar'

     class GravatarTest < Test::Unit::TestCase
       def test_builds_gravatar_url
         g = Grabatar::Gravatar.new("bphogan@gmail.com")
         assert_equal "http://www.gravatar.com/avatar/
                       6ef8cb7cd7cd58077f0b57e4fa49a969", g.avatar_url
       end
     end




twitter: bphogan
email: brianhogan at napcs.com
Then write the code
   lib/grabatar/gravatar.rb

      module Grabatar
        class Gravatar
          require 'digest/md5'

           def initialize(email)
             @email = email
           end

           def avatar_url
             hash = Digest::MD5.hexdigest(@email)
             "http://www.gravatar.com/avatar/#{hash}"
           end

        end
      end


twitter: bphogan
email: brianhogan at napcs.com
Then write the code
   lib/grabatar/gravatar.rb

      module Grabatar
        class Gravatar
          require 'digest/md5'

           def initialize(email)
             @email = email
           end

           def avatar_url
             hash = Digest::MD5.hexdigest(@email)
             "http://www.gravatar.com/avatar/#{hash}"
           end

        end
      end


twitter: bphogan
email: brianhogan at napcs.com
Then write the code
   lib/grabatar/gravatar.rb

      module Grabatar
        class Gravatar
          require 'digest/md5'

           def initialize(email)
             @email = email
           end

           def avatar_url
             hash = Digest::MD5.hexdigest(@email)
             "http://www.gravatar.com/avatar/#{hash}"
           end

        end
      end


twitter: bphogan
email: brianhogan at napcs.com
Then write the code
   lib/grabatar/gravatar.rb

      module Grabatar
        class Gravatar
          require 'digest/md5'

           def initialize(email)
             @email = email
           end

           def avatar_url
             hash = Digest::MD5.hexdigest(@email)
             "http://www.gravatar.com/avatar/#{hash}"
           end

        end
      end


twitter: bphogan
email: brianhogan at napcs.com
Step two: Make A
                         Gemspec


twitter: bphogan
email: brianhogan at napcs.com
Gemspecs are easy.
   grabatar.gemspec

     require 'lib/grabatar/version'
     Gem::Specification.new do |s|
       s.name = "grabatar"
       s.version = Grabatar::VERSION
       s.summary = "Fetch avatar image URLs from Gravatar"
       s.authors = ["Brian Hogan"]
       s.email = ["bphogan@gmail.com"]
       s.files = [
         "lib/grabatar.rb",
         "lib/grabatar/version.rb",
         "lib/grabatar/gravatar.rb",
         "lib/grabatar/railtie.rb",
         "lib/grabatar/view_helpers.rb"
       ]
     end


twitter: bphogan
email: brianhogan at napcs.com
Gemspecs are easy.
   grabatar.gemspec

     require 'lib/grabatar/version'
     Gem::Specification.new do |s|
       s.name = "grabatar"
       s.version = Grabatar::VERSION
       s.summary = "Fetch avatar image URLs from Gravatar"
       s.authors = ["Brian Hogan"]
       s.email = ["bphogan@gmail.com"]
       s.files = [
         "lib/grabatar.rb",
         "lib/grabatar/version.rb",
         "lib/grabatar/gravatar.rb",
         "lib/grabatar/railtie.rb",
         "lib/grabatar/view_helpers.rb"
       ]
     end


twitter: bphogan
email: brianhogan at napcs.com
Gemspecs are easy.
   grabatar.gemspec

     require 'lib/grabatar/version'
     Gem::Specification.new do |s|
       s.name = "grabatar"
       s.version = Grabatar::VERSION
       s.summary = "Fetch avatar image URLs from Gravatar"
       s.authors = ["Brian Hogan"]
       s.email = ["bphogan@gmail.com"]
       s.files = [
         "lib/grabatar.rb",
         "lib/grabatar/version.rb",
         "lib/grabatar/gravatar.rb",
         "lib/grabatar/railtie.rb",
         "lib/grabatar/view_helpers.rb"
       ]
     end


twitter: bphogan
email: brianhogan at napcs.com
Gemspecs are easy.
   grabatar.gemspec

     require 'lib/grabatar/version'
     Gem::Specification.new do |s|
       s.name = "grabatar"
       s.version = Grabatar::VERSION
       s.summary = "Fetch avatar image URLs from Gravatar"
       s.authors = ["Brian Hogan"]
       s.email = ["bphogan@gmail.com"]
       s.files = [
         "lib/grabatar.rb",
         "lib/grabatar/version.rb",
         "lib/grabatar/gravatar.rb",
         "lib/grabatar/railtie.rb",
         "lib/grabatar/view_helpers.rb"
       ]
     end


twitter: bphogan
email: brianhogan at napcs.com
The manifest




twitter: bphogan
email: brianhogan at napcs.com
bundle gem is bad for you
     s.files                = `git ls-files`.split("n")
     s.test_files           = `git ls-files --
                               {test,spec,features}/*`.split("n")
     s.executables          = `git ls-files -- bin/*`
                               .split("n").map{ |f| File.basename(f) }




twitter: bphogan
email: brianhogan at napcs.com
What lies beneath
           • .DS_Store
           • thumbs.db
           • ~whatever.rb
           • whatever.mine.rb
           • Step 3: Rake
           • Test::Unit tasks
twitter: bphogan
email: brianhogan at napcs.com
Craft your manifest by hand
    s.files = [
      "lib/grabatar.rb",
      "lib/grabatar/version.rb",
      "lib/grabatar/gravatar.rb",
      "lib/grabatar/railtie.rb",
      "lib/grabatar/view_helpers.rb"
    ]




twitter: bphogan
email: brianhogan at napcs.com
Build and install the gem
     $ gem build grabatar.gemspec
     $ gem install grabatar-0-0-1.gem




twitter: bphogan
email: brianhogan at napcs.com
Step 4: Rails gems



twitter: bphogan
email: brianhogan at napcs.com
Test first
   test/view_helpers_test.rb

     require 'test/unit'
     require 'grabatar/gravatar'
     require 'grabatar/view_helpers'

     class ViewHelpers < Test::Unit::TestCase
       include Grabatar::ViewHelpers
       def test_generates_avatar_url
         assert_equal
            "http://www.gravatar.com/avatar
             /6ef8cb7cd7cd58077f0b57e4fa49a969",
             gravatar_url_for("bphogan@gmail.com")
       end
     end




twitter: bphogan
email: brianhogan at napcs.com
Test first
   test/view_helpers_test.rb

     require 'test/unit'
     require 'grabatar/gravatar'
     require 'grabatar/view_helpers'

     class ViewHelpers < Test::Unit::TestCase
       include Grabatar::ViewHelpers
       def test_generates_avatar_url
         assert_equal
            "http://www.gravatar.com/avatar
             /6ef8cb7cd7cd58077f0b57e4fa49a969",
             gravatar_url_for("bphogan@gmail.com")
       end
     end




twitter: bphogan
email: brianhogan at napcs.com
Create a helper
   lib/grabatar/view_helpers.rb


      module Grabatar
        module ViewHelpers
          def gravatar_url_for(email)
            Grabatar::Gravatar.new(email).avatar_url
          end
        end
      end




twitter: bphogan
email: brianhogan at napcs.com
Railties



twitter: bphogan
email: brianhogan at napcs.com
Include the Helper
   lib/grabatar/railtie.rb


     module Grabatar
       class Railtie < Rails::Railtie
         initializer "grabatar.view_helpers" do
           ActionView::Base.send :include, ViewHelpers
         end
       end
     end




twitter: bphogan
email: brianhogan at napcs.com
Only load the Railtie if we have Rails
 lib/grabatar.rb


   require 'grabatar/railtie' if defined?(Rails)




twitter: bphogan
email: brianhogan at napcs.com
Making a CLI tool



twitter: bphogan
email: brianhogan at napcs.com
Add a bin folder with
                    the file!


twitter: bphogan
email: brianhogan at napcs.com
The CLI program
   bin/grabatar


     #!/usr/bin/env ruby
     require 'grabatar'

     puts "Grabatar v#{Grabatar::VERSION}"

     email = ARGV[0]

     if email.nil?
       puts "Usage: grabatar <youremail@server.com>"
     else
       g = Grabatar::Gravatar.new(email)
       puts g.avatar_url
     end




twitter: bphogan
email: brianhogan at napcs.com
The CLI program
   bin/grabatar


     #!/usr/bin/env ruby
     require 'grabatar'

     puts "Grabatar v#{Grabatar::VERSION}"

     email = ARGV[0]

     if email.nil?
       puts "Usage: grabatar <youremail@server.com>"
     else
       g = Grabatar::Gravatar.new(email)
       puts g.avatar_url
     end




twitter: bphogan
email: brianhogan at napcs.com
The CLI program
   bin/grabatar


     #!/usr/bin/env ruby
     require 'grabatar'

     puts "Grabatar v#{Grabatar::VERSION}"

     email = ARGV[0]

     if email.nil?
       puts "Usage: grabatar <youremail@server.com>"
     else
       g = Grabatar::Gravatar.new(email)
       puts g.avatar_url
     end




twitter: bphogan
email: brianhogan at napcs.com
Running it

     $ grabatar bphogan@gmail.com
     Grabatar v0.0.2
     http://www.gravatar.com/avatar/6ef8cb7cd7cd58077f0b57e4fa49a969




twitter: bphogan
email: brianhogan at napcs.com
Who wants code?
                     http://github.com/napcs/grabatar




twitter: bphogan
email: brianhogan at napcs.com
Thanks!
                                 http://spkr8.com/t/8181




twitter: bphogan
email: brianhogan at napcs.com

Mais conteúdo relacionado

Mais procurados

Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSHannes Hapke
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010singingfish
 
Beware the potholes on the road to serverless
Beware the potholes on the road to serverlessBeware the potholes on the road to serverless
Beware the potholes on the road to serverlessYan Cui
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax ApplicationsSiarhei Barysiuk
 
Looking Back to Move Forward: Building the Modern Web
Looking Back to Move Forward: Building the Modern WebLooking Back to Move Forward: Building the Modern Web
Looking Back to Move Forward: Building the Modern WebRachel Andrew
 
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
 
HTTP/2 BrightonSEO 2018
HTTP/2 BrightonSEO 2018HTTP/2 BrightonSEO 2018
HTTP/2 BrightonSEO 2018Tom Anthony
 
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
 
Ajax to the Moon
Ajax to the MoonAjax to the Moon
Ajax to the Moondavejohnson
 
Web Development with Python and Django
Web Development with Python and DjangoWeb Development with Python and Django
Web Development with Python and DjangoMichael Pirnat
 
DEF CON 27 - BEN SADEGHIPOUR - owning the clout through ssrf and pdf generators
DEF CON 27 - BEN SADEGHIPOUR  - owning the clout through ssrf and pdf generatorsDEF CON 27 - BEN SADEGHIPOUR  - owning the clout through ssrf and pdf generators
DEF CON 27 - BEN SADEGHIPOUR - owning the clout through ssrf and pdf generatorsFelipe Prado
 
Ruby Isn't Just About Rails
Ruby Isn't Just About RailsRuby Isn't Just About Rails
Ruby Isn't Just About RailsAdam Wiggins
 
SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...
SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...
SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...Distilled
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Ryan Weaver
 

Mais procurados (20)

Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
 
Beware the potholes on the road to serverless
Beware the potholes on the road to serverlessBeware the potholes on the road to serverless
Beware the potholes on the road to serverless
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
 
Looking Back to Move Forward: Building the Modern Web
Looking Back to Move Forward: Building the Modern WebLooking Back to Move Forward: Building the Modern Web
Looking Back to Move Forward: Building the Modern Web
 
HTML 5 & CSS 3
HTML 5 & CSS 3HTML 5 & CSS 3
HTML 5 & CSS 3
 
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
 
HTTP/2 BrightonSEO 2018
HTTP/2 BrightonSEO 2018HTTP/2 BrightonSEO 2018
HTTP/2 BrightonSEO 2018
 
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
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
Ajax to the Moon
Ajax to the MoonAjax to the Moon
Ajax to the Moon
 
Web Development with Python and Django
Web Development with Python and DjangoWeb Development with Python and Django
Web Development with Python and Django
 
DEF CON 27 - BEN SADEGHIPOUR - owning the clout through ssrf and pdf generators
DEF CON 27 - BEN SADEGHIPOUR  - owning the clout through ssrf and pdf generatorsDEF CON 27 - BEN SADEGHIPOUR  - owning the clout through ssrf and pdf generators
DEF CON 27 - BEN SADEGHIPOUR - owning the clout through ssrf and pdf generators
 
Django a whirlwind tour
Django   a whirlwind tourDjango   a whirlwind tour
Django a whirlwind tour
 
Ruby Isn't Just About Rails
Ruby Isn't Just About RailsRuby Isn't Just About Rails
Ruby Isn't Just About Rails
 
SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...
SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...
SearchLove San Diego 2018 | Tom Anthony | An Introduction to HTTP/2 & Service...
 
How cgi scripting works
How cgi scripting worksHow cgi scripting works
How cgi scripting works
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
 

Semelhante a Building A Gem From Scratch

Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientAdam Wiggins
 
Merb Slices
Merb SlicesMerb Slices
Merb Sliceshassox
 
Djabot – Python Jabber Bot
Djabot – Python Jabber BotDjabot – Python Jabber Bot
Djabot – Python Jabber Botmarekkuziel
 
Freeing the cloud, one service at a time
Freeing the cloud, one service at a timeFreeing the cloud, one service at a time
Freeing the cloud, one service at a timeFrancois Marier
 
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기raccoony
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manormartinbtt
 
2018 the conf put git to work - increase the quality of your rails project...
2018 the conf   put git to work -  increase the quality of your rails project...2018 the conf   put git to work -  increase the quality of your rails project...
2018 the conf put git to work - increase the quality of your rails project...Rodrigo Urubatan
 
ChefConf 2012 Spiceweasel
ChefConf 2012 SpiceweaselChefConf 2012 Spiceweasel
ChefConf 2012 SpiceweaselMatt Ray
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby TeamArto Artnik
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with CucumberBen Mabey
 
Sinatra Rack And Middleware
Sinatra Rack And MiddlewareSinatra Rack And Middleware
Sinatra Rack And MiddlewareBen Schwarz
 
Agile Development With Hobo
Agile Development With HoboAgile Development With Hobo
Agile Development With HoboEvarist Lobo
 

Semelhante a Building A Gem From Scratch (20)

Intro to Ruby
Intro to RubyIntro to Ruby
Intro to Ruby
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
 
Merb Slices
Merb SlicesMerb Slices
Merb Slices
 
Djabot – Python Jabber Bot
Djabot – Python Jabber BotDjabot – Python Jabber Bot
Djabot – Python Jabber Bot
 
Freeing the cloud, one service at a time
Freeing the cloud, one service at a timeFreeing the cloud, one service at a time
Freeing the cloud, one service at a time
 
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기
 
Capistrano Overview
Capistrano OverviewCapistrano Overview
Capistrano Overview
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manor
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
2018 the conf put git to work - increase the quality of your rails project...
2018 the conf   put git to work -  increase the quality of your rails project...2018 the conf   put git to work -  increase the quality of your rails project...
2018 the conf put git to work - increase the quality of your rails project...
 
ChefConf 2012 Spiceweasel
ChefConf 2012 SpiceweaselChefConf 2012 Spiceweasel
ChefConf 2012 Spiceweasel
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
Life on the Edge
Life on the EdgeLife on the Edge
Life on the Edge
 
Capistrano
CapistranoCapistrano
Capistrano
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
 
Sinatra Rack And Middleware
Sinatra Rack And MiddlewareSinatra Rack And Middleware
Sinatra Rack And Middleware
 
Agile Development With Hobo
Agile Development With HoboAgile Development With Hobo
Agile Development With Hobo
 
Capistrano
CapistranoCapistrano
Capistrano
 

Mais de 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
 
Web Development with CoffeeScript and Sass
Web Development with CoffeeScript and SassWeb Development with CoffeeScript and Sass
Web Development with CoffeeScript and SassBrian 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
 

Mais de 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
 
Web Development with CoffeeScript and Sass
Web Development with CoffeeScript and SassWeb Development with CoffeeScript and Sass
Web Development with CoffeeScript and Sass
 
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 - 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
 

Último

Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 

Último (20)

Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 

Building A Gem From Scratch

  • 1. Building A Gem From Scratch Madison Ruby, 2011 twitter: bphogan email: brianhogan at napcs.com
  • 2. What's A Gem? twitter: bphogan email: brianhogan at napcs.com
  • 3. The (normal) Process • Come up with an idea • write some code • Release a gem • Beg people to write tests for you twitter: bphogan email: brianhogan at napcs.com
  • 4. Our process • Come up with an idea and write some code • Throw all that code away • Rewrite it with tests as we go • Release it as a Gem • Enjoy fame and fortune twitter: bphogan email: brianhogan at napcs.com
  • 5. Grabatar (a gem to grab Gravatar URLs) http://www.gravatar.com/avatar/ 6ef8cb7cd7cd58077f0b57e4fa49a969 twitter: bphogan email: brianhogan at napcs.com
  • 6. Step one: Build tested, working code twitter: bphogan email: brianhogan at napcs.com
  • 7. The basic structure of a Gem gemname.gemspec lib/ gemname version.rb anotherfile.rb gemname.rb twitter: bphogan email: brianhogan at napcs.com
  • 8. Tests, Tests, Tests! twitter: bphogan email: brianhogan at napcs.com
  • 9. Test::Unit test somefile_test.rb twitter: bphogan email: brianhogan at napcs.com
  • 10. Write the test test/grabatar_test.rb require 'test/unit' require 'lib/grabatar' class GrabatarTest < Test::Unit::TestCase def test_displays_version assert Grabatar::VERSION end end twitter: bphogan email: brianhogan at napcs.com
  • 11. Implement the code lib/grabatar/version.rb module Grabatar VERSION = "0.0.2" end twitter: bphogan email: brianhogan at napcs.com
  • 12. Add to the main Ruby file: lib/grabatar.rb require 'grabatar/version' twitter: bphogan email: brianhogan at napcs.com
  • 14. Write the test first... test/gravatar_helper.rb require 'test/unit' require 'grabatar' class GravatarTest < Test::Unit::TestCase def test_builds_gravatar_url g = Grabatar::Gravatar.new("bphogan@gmail.com") assert_equal "http://www.gravatar.com/avatar/ 6ef8cb7cd7cd58077f0b57e4fa49a969", g.avatar_url end end twitter: bphogan email: brianhogan at napcs.com
  • 15. Then write the code lib/grabatar/gravatar.rb module Grabatar class Gravatar require 'digest/md5' def initialize(email) @email = email end def avatar_url hash = Digest::MD5.hexdigest(@email) "http://www.gravatar.com/avatar/#{hash}" end end end twitter: bphogan email: brianhogan at napcs.com
  • 16. Then write the code lib/grabatar/gravatar.rb module Grabatar class Gravatar require 'digest/md5' def initialize(email) @email = email end def avatar_url hash = Digest::MD5.hexdigest(@email) "http://www.gravatar.com/avatar/#{hash}" end end end twitter: bphogan email: brianhogan at napcs.com
  • 17. Then write the code lib/grabatar/gravatar.rb module Grabatar class Gravatar require 'digest/md5' def initialize(email) @email = email end def avatar_url hash = Digest::MD5.hexdigest(@email) "http://www.gravatar.com/avatar/#{hash}" end end end twitter: bphogan email: brianhogan at napcs.com
  • 18. Then write the code lib/grabatar/gravatar.rb module Grabatar class Gravatar require 'digest/md5' def initialize(email) @email = email end def avatar_url hash = Digest::MD5.hexdigest(@email) "http://www.gravatar.com/avatar/#{hash}" end end end twitter: bphogan email: brianhogan at napcs.com
  • 19. Step two: Make A Gemspec twitter: bphogan email: brianhogan at napcs.com
  • 20. Gemspecs are easy. grabatar.gemspec require 'lib/grabatar/version' Gem::Specification.new do |s| s.name = "grabatar" s.version = Grabatar::VERSION s.summary = "Fetch avatar image URLs from Gravatar" s.authors = ["Brian Hogan"] s.email = ["bphogan@gmail.com"] s.files = [ "lib/grabatar.rb", "lib/grabatar/version.rb", "lib/grabatar/gravatar.rb", "lib/grabatar/railtie.rb", "lib/grabatar/view_helpers.rb" ] end twitter: bphogan email: brianhogan at napcs.com
  • 21. Gemspecs are easy. grabatar.gemspec require 'lib/grabatar/version' Gem::Specification.new do |s| s.name = "grabatar" s.version = Grabatar::VERSION s.summary = "Fetch avatar image URLs from Gravatar" s.authors = ["Brian Hogan"] s.email = ["bphogan@gmail.com"] s.files = [ "lib/grabatar.rb", "lib/grabatar/version.rb", "lib/grabatar/gravatar.rb", "lib/grabatar/railtie.rb", "lib/grabatar/view_helpers.rb" ] end twitter: bphogan email: brianhogan at napcs.com
  • 22. Gemspecs are easy. grabatar.gemspec require 'lib/grabatar/version' Gem::Specification.new do |s| s.name = "grabatar" s.version = Grabatar::VERSION s.summary = "Fetch avatar image URLs from Gravatar" s.authors = ["Brian Hogan"] s.email = ["bphogan@gmail.com"] s.files = [ "lib/grabatar.rb", "lib/grabatar/version.rb", "lib/grabatar/gravatar.rb", "lib/grabatar/railtie.rb", "lib/grabatar/view_helpers.rb" ] end twitter: bphogan email: brianhogan at napcs.com
  • 23. Gemspecs are easy. grabatar.gemspec require 'lib/grabatar/version' Gem::Specification.new do |s| s.name = "grabatar" s.version = Grabatar::VERSION s.summary = "Fetch avatar image URLs from Gravatar" s.authors = ["Brian Hogan"] s.email = ["bphogan@gmail.com"] s.files = [ "lib/grabatar.rb", "lib/grabatar/version.rb", "lib/grabatar/gravatar.rb", "lib/grabatar/railtie.rb", "lib/grabatar/view_helpers.rb" ] end twitter: bphogan email: brianhogan at napcs.com
  • 24. The manifest twitter: bphogan email: brianhogan at napcs.com
  • 25. bundle gem is bad for you s.files = `git ls-files`.split("n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("n") s.executables = `git ls-files -- bin/*` .split("n").map{ |f| File.basename(f) } twitter: bphogan email: brianhogan at napcs.com
  • 26. What lies beneath • .DS_Store • thumbs.db • ~whatever.rb • whatever.mine.rb • Step 3: Rake • Test::Unit tasks twitter: bphogan email: brianhogan at napcs.com
  • 27. Craft your manifest by hand s.files = [ "lib/grabatar.rb", "lib/grabatar/version.rb", "lib/grabatar/gravatar.rb", "lib/grabatar/railtie.rb", "lib/grabatar/view_helpers.rb" ] twitter: bphogan email: brianhogan at napcs.com
  • 28. Build and install the gem $ gem build grabatar.gemspec $ gem install grabatar-0-0-1.gem twitter: bphogan email: brianhogan at napcs.com
  • 29. Step 4: Rails gems twitter: bphogan email: brianhogan at napcs.com
  • 30. Test first test/view_helpers_test.rb require 'test/unit' require 'grabatar/gravatar' require 'grabatar/view_helpers' class ViewHelpers < Test::Unit::TestCase include Grabatar::ViewHelpers def test_generates_avatar_url assert_equal "http://www.gravatar.com/avatar /6ef8cb7cd7cd58077f0b57e4fa49a969", gravatar_url_for("bphogan@gmail.com") end end twitter: bphogan email: brianhogan at napcs.com
  • 31. Test first test/view_helpers_test.rb require 'test/unit' require 'grabatar/gravatar' require 'grabatar/view_helpers' class ViewHelpers < Test::Unit::TestCase include Grabatar::ViewHelpers def test_generates_avatar_url assert_equal "http://www.gravatar.com/avatar /6ef8cb7cd7cd58077f0b57e4fa49a969", gravatar_url_for("bphogan@gmail.com") end end twitter: bphogan email: brianhogan at napcs.com
  • 32. Create a helper lib/grabatar/view_helpers.rb module Grabatar module ViewHelpers def gravatar_url_for(email) Grabatar::Gravatar.new(email).avatar_url end end end twitter: bphogan email: brianhogan at napcs.com
  • 34. Include the Helper lib/grabatar/railtie.rb module Grabatar class Railtie < Rails::Railtie initializer "grabatar.view_helpers" do ActionView::Base.send :include, ViewHelpers end end end twitter: bphogan email: brianhogan at napcs.com
  • 35. Only load the Railtie if we have Rails lib/grabatar.rb require 'grabatar/railtie' if defined?(Rails) twitter: bphogan email: brianhogan at napcs.com
  • 36. Making a CLI tool twitter: bphogan email: brianhogan at napcs.com
  • 37. Add a bin folder with the file! twitter: bphogan email: brianhogan at napcs.com
  • 38. The CLI program bin/grabatar #!/usr/bin/env ruby require 'grabatar' puts "Grabatar v#{Grabatar::VERSION}" email = ARGV[0] if email.nil? puts "Usage: grabatar <youremail@server.com>" else g = Grabatar::Gravatar.new(email) puts g.avatar_url end twitter: bphogan email: brianhogan at napcs.com
  • 39. The CLI program bin/grabatar #!/usr/bin/env ruby require 'grabatar' puts "Grabatar v#{Grabatar::VERSION}" email = ARGV[0] if email.nil? puts "Usage: grabatar <youremail@server.com>" else g = Grabatar::Gravatar.new(email) puts g.avatar_url end twitter: bphogan email: brianhogan at napcs.com
  • 40. The CLI program bin/grabatar #!/usr/bin/env ruby require 'grabatar' puts "Grabatar v#{Grabatar::VERSION}" email = ARGV[0] if email.nil? puts "Usage: grabatar <youremail@server.com>" else g = Grabatar::Gravatar.new(email) puts g.avatar_url end twitter: bphogan email: brianhogan at napcs.com
  • 41. Running it $ grabatar bphogan@gmail.com Grabatar v0.0.2 http://www.gravatar.com/avatar/6ef8cb7cd7cd58077f0b57e4fa49a969 twitter: bphogan email: brianhogan at napcs.com
  • 42. Who wants code? http://github.com/napcs/grabatar twitter: bphogan email: brianhogan at napcs.com
  • 43. Thanks! http://spkr8.com/t/8181 twitter: bphogan email: brianhogan at napcs.com

Notas do Editor

  1. \n
  2. Who here knows what a Gem is? Who&apos;s built a gem?\n
  3. \n
  4. \n
  5. Simple gem that fetches the Gravatar URL based on the given email\n
  6. This is the easy part.\n
  7. a lib folder, a &quot;main&quot; file that includes our other files\n
  8. Because they make for good code.\n
  9. Because it&apos;s there. I think Gems should try to have as few dependencies as possible.\n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. By hand. \n
  21. \n
  22. \n
  23. \n
  24. Lists all the files you wish to release with your Gem.\n
  25. It sure is handy, but its generated manifest is overkill. It depends on git. Maybe it&amp;#x2019;s not bad for you, but it sure makes me uncomfortable. It also requires that I use Git. I can remove these lines trivially. But it&amp;#x2019;s still uncomfortable.\n
  26. Things that automatically build manifests can (and do) accidentally include things like this, and more. And you can&apos;t put exceptions in for every possible type of IDE backup file or hidden folder a contributor might have.\n
  27. This way, you ensure that what&apos;s in the Gem is what you want, and what your contributors want. \n
  28. \n
  29. We can make our gems work with Rails. Let&apos;s make a really simple Rails helper\n
  30. Our helper will be a module, so we write a test that includes the module and tests that it returns the right result.\n
  31. Our helper will be a module, so we write a test that includes the module and tests that it returns the right result.\n
  32. \n
  33. We create a new class that inherits from Railtie and then mix our module into the view helpers\n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n