Your SlideShare is downloading. ×
Building A Gem From Scratch
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Building A Gem From Scratch

1,566
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 …

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

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,566
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • Who here knows what a Gem is? Who's built a gem?\n
  • \n
  • \n
  • Simple gem that fetches the Gravatar URL based on the given email\n
  • This is the easy part.\n
  • a lib folder, a "main" file that includes our other files\n
  • Because they make for good code.\n
  • Because it's there. I think Gems should try to have as few dependencies as possible.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • By hand. \n
  • \n
  • \n
  • \n
  • Lists all the files you wish to release with your Gem.\n
  • It sure is handy, but its generated manifest is overkill. It depends on git. Maybe it’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’s still uncomfortable.\n
  • Things that automatically build manifests can (and do) accidentally include things like this, and more. And you can't put exceptions in for every possible type of IDE backup file or hidden folder a contributor might have.\n
  • This way, you ensure that what's in the Gem is what you want, and what your contributors want. \n
  • \n
  • We can make our gems work with Rails. Let's make a really simple Rails helper\n
  • Our helper will be a module, so we write a test that includes the module and tests that it returns the right result.\n
  • Our helper will be a module, so we write a test that includes the module and tests that it returns the right result.\n
  • \n
  • We create a new class that inherits from Railtie and then mix our module into the view helpers\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Building A Gem From Scratch Madison Ruby, 2011twitter: bphoganemail: brianhogan at napcs.com
    • 2. Whats A Gem?twitter: bphoganemail: 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 youtwitter: bphoganemail: 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 fortunetwitter: bphoganemail: brianhogan at napcs.com
    • 5. Grabatar (a gem to grab Gravatar URLs) http://www.gravatar.com/avatar/ 6ef8cb7cd7cd58077f0b57e4fa49a969twitter: bphoganemail: brianhogan at napcs.com
    • 6. Step one: Build tested, working codetwitter: bphoganemail: brianhogan at napcs.com
    • 7. The basic structure of a Gem gemname.gemspec lib/ gemname version.rb anotherfile.rb gemname.rbtwitter: bphoganemail: brianhogan at napcs.com
    • 8. Tests, Tests, Tests!twitter: bphoganemail: brianhogan at napcs.com
    • 9. Test::Unit test somefile_test.rbtwitter: bphoganemail: 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 endtwitter: bphoganemail: brianhogan at napcs.com
    • 11. Implement the code lib/grabatar/version.rb module Grabatar VERSION = "0.0.2" endtwitter: bphoganemail: brianhogan at napcs.com
    • 12. Add to the main Ruby file: lib/grabatar.rb require grabatar/versiontwitter: bphoganemail: brianhogan at napcs.com
    • 13. Repeat.twitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: brianhogan at napcs.com
    • 19. Step two: Make A Gemspectwitter: bphoganemail: 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" ] endtwitter: bphoganemail: 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" ] endtwitter: bphoganemail: 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" ] endtwitter: bphoganemail: 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" ] endtwitter: bphoganemail: brianhogan at napcs.com
    • 24. The manifesttwitter: bphoganemail: 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: bphoganemail: brianhogan at napcs.com
    • 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. 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. Build and install the gem $ gem build grabatar.gemspec $ gem install grabatar-0-0-1.gemtwitter: bphoganemail: brianhogan at napcs.com
    • 29. Step 4: Rails gemstwitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: brianhogan at napcs.com
    • 33. Railtiestwitter: bphoganemail: 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 endtwitter: bphoganemail: brianhogan at napcs.com
    • 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. Making a CLI tooltwitter: bphoganemail: brianhogan at napcs.com
    • 37. Add a bin folder with the file!twitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: 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 endtwitter: bphoganemail: brianhogan at napcs.com
    • 41. Running it $ grabatar bphogan@gmail.com Grabatar v0.0.2 http://www.gravatar.com/avatar/6ef8cb7cd7cd58077f0b57e4fa49a969twitter: bphoganemail: brianhogan at napcs.com
    • 42. Who wants code? http://github.com/napcs/grabatartwitter: bphoganemail: brianhogan at napcs.com
    • 43. Thanks! http://spkr8.com/t/8181twitter: bphoganemail: brianhogan at napcs.com