Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Building A Gem From Scratch

2,156 views

Published on

If you've ever looked into how to create Gems, you've probably seen a bunch of ways to do that. Project generators like Hoe, Jeweler, and the like offer some nice ways to get started, but they may often be overkill for many projects. If you're just starting out, why not learn to do it from scratch?

In this talk, we'll create our own gem from scratch, using only things that are provided by Ruby, its standard library, and RubyGems to craft a simple gem.

You'll learn how to set up a project, how to write and run tests, how to use Rake to quickly build the gem, and even how to create a gem that installs an executable command-line program.

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

Building A Gem From Scratch

  1. 1. Building A Gem From Scratch Madison Ruby, 2011twitter: bphoganemail: brianhogan at napcs.com
  2. 2. Whats A Gem?twitter: bphoganemail: brianhogan at napcs.com
  3. 3. The (normal) Process • Come up with an idea • write some code • Release a gem • Beg people to write tests for youtwitter: bphoganemail: brianhogan at napcs.com
  4. 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 fortunetwitter: bphoganemail: brianhogan at napcs.com
  5. 5. Grabatar (a gem to grab Gravatar URLs) http://www.gravatar.com/avatar/ 6ef8cb7cd7cd58077f0b57e4fa49a969twitter: bphoganemail: brianhogan at napcs.com
  6. 6. Step one: Build tested, working codetwitter: bphoganemail: brianhogan at napcs.com
  7. 7. The basic structure of a Gem gemname.gemspec lib/ gemname version.rb anotherfile.rb gemname.rbtwitter: bphoganemail: brianhogan at napcs.com
  8. 8. Tests, Tests, Tests!twitter: bphoganemail: brianhogan at napcs.com
  9. 9. Test::Unit test somefile_test.rbtwitter: bphoganemail: brianhogan at napcs.com
  10. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  11. 11. Implement the code lib/grabatar/version.rb module Grabatar VERSION = "0.0.2" endtwitter: bphoganemail: brianhogan at napcs.com
  12. 12. Add to the main Ruby file: lib/grabatar.rb require grabatar/versiontwitter: bphoganemail: brianhogan at napcs.com
  13. 13. Repeat.twitter: bphoganemail: brianhogan at napcs.com
  14. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  15. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  16. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  17. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  18. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  19. 19. Step two: Make A Gemspectwitter: bphoganemail: brianhogan at napcs.com
  20. 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" ] endtwitter: bphoganemail: brianhogan at napcs.com
  21. 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" ] endtwitter: bphoganemail: brianhogan at napcs.com
  22. 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" ] endtwitter: bphoganemail: brianhogan at napcs.com
  23. 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" ] endtwitter: bphoganemail: brianhogan at napcs.com
  24. 24. The manifesttwitter: bphoganemail: brianhogan at napcs.com
  25. 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: bphoganemail: brianhogan at napcs.com
  26. 26. What lies beneath • .DS_Store • thumbs.db • ~whatever.rb • whatever.mine.rb • Step 3: Rake • Test::Unit taskstwitter: bphoganemail: brianhogan at napcs.com
  27. 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: bphoganemail: brianhogan at napcs.com
  28. 28. Build and install the gem $ gem build grabatar.gemspec $ gem install grabatar-0-0-1.gemtwitter: bphoganemail: brianhogan at napcs.com
  29. 29. Step 4: Rails gemstwitter: bphoganemail: brianhogan at napcs.com
  30. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  31. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  32. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  33. 33. Railtiestwitter: bphoganemail: brianhogan at napcs.com
  34. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  35. 35. Only load the Railtie if we have Rails lib/grabatar.rb require grabatar/railtie if defined?(Rails)twitter: bphoganemail: brianhogan at napcs.com
  36. 36. Making a CLI tooltwitter: bphoganemail: brianhogan at napcs.com
  37. 37. Add a bin folder with the file!twitter: bphoganemail: brianhogan at napcs.com
  38. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  39. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  40. 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 endtwitter: bphoganemail: brianhogan at napcs.com
  41. 41. Running it $ grabatar bphogan@gmail.com Grabatar v0.0.2 http://www.gravatar.com/avatar/6ef8cb7cd7cd58077f0b57e4fa49a969twitter: bphoganemail: brianhogan at napcs.com
  42. 42. Who wants code? http://github.com/napcs/grabatartwitter: bphoganemail: brianhogan at napcs.com
  43. 43. Thanks! http://spkr8.com/t/8181twitter: bphoganemail: brianhogan at napcs.com

×