Table of Contents
- Prerequisites
- Setting Up Your Gem Structure
- Writing the Gem Code
- Adding a Version File
- Creating a Gemspec
- Testing Your Gem
- Building the Gem
- Publishing to RubyGems.org
- Updating Your Gem
- Conclusion
- References
Prerequisites
Before diving in, ensure you have the following tools installed:
-
Ruby: Ruby 2.5 or later is recommended. Check your version with:
ruby -v -
Bundler: A tool for managing Ruby dependencies. Install it with:
gem install bundler -
RubyGems Account: To publish your gem, sign up for a free account at RubyGems.org.
Setting Up Your Gem Structure
Ruby Gems follow a standard directory structure. Instead of creating files manually, use Bundler to generate a skeleton for you.
Step 1: Generate the Gem Skeleton
Run this command, replacing hello_gem with your gem’s name (use lowercase with underscores for multi-word names):
bundle gem hello_gem
Bundler will create a directory named hello_gem with the following structure:
hello_gem/
├── .gitignore # Ignores unnecessary files in Git
├── .rspec # RSpec configuration
├── Gemfile # Dependencies
├── README.md # Documentation for your gem
├── Rakefile # Tasks (e.g., running tests)
├── bin/ # Executable scripts (if needed)
│ ├── console # Interactive console for testing
│ └── setup # Setup script
├── hello_gem.gemspec # Gem metadata (critical for publishing)
├── lib/ # Main code directory
│ ├── hello_gem/ # Namespaced code
│ │ └── version.rb # Version number
│ └── hello_gem.rb # Entry point for your gem
└── spec/ # Test directory
├── hello_gem_spec.rb # Tests for your gem
└── spec_helper.rb # RSpec setup
What Each Directory/File Does:
lib/: Contains your gem’s code. Thehello_gem.rbfile is the “entry point”—when usersrequire "hello_gem", Ruby loads this file.spec/: Home for tests (we’ll use RSpec for testing).hello_gem.gemspec: A Ruby file that defines metadata (name, version, dependencies) needed to build and publish the gem.
Writing the Gem Code
Let’s add functionality to our gem. For this example, we’ll build a simple gem that greets users by name.
Step 1: Edit the Main Code File
Open lib/hello_gem.rb and replace its contents with:
# lib/hello_gem.rb
require "hello_gem/version"
module HelloGem
def self.greet(name = "World")
"Hello, #{name}!"
end
end
This defines a module HelloGem with a class method greet that takes an optional name parameter (defaulting to “World”) and returns a greeting string.
Adding a Version File
Every gem needs a version number. RubyGems uses Semantic Versioning (MAJOR.MINOR.PATCH), where:
- MAJOR: Breaking changes (e.g., 1.0.0 → 2.0.0).
- MINOR: New features (e.g., 1.0.0 → 1.1.0).
- PATCH: Bug fixes (e.g., 1.0.0 → 1.0.1).
Step 1: Set the Initial Version
Open lib/hello_gem/version.rb (auto-generated by Bundler) and set the version:
# lib/hello_gem/version.rb
module HelloGem
VERSION = "0.1.0" # Initial version: 0.1.0 (MINOR.PATCH for 0.x.y)
end
Creating a Gemspec
The .gemspec file is critical—it tells RubyGems about your gem. Open hello_gem.gemspec and update it with your details. Here’s a complete example:
# hello_gem.gemspec
require_relative "lib/hello_gem/version"
Gem::Specification.new do |spec|
spec.name = "hello_gem" # Must match the gem name (no spaces!)
spec.version = HelloGem::VERSION
spec.authors = ["Your Name"]
spec.email = ["[email protected]"]
spec.summary = "A simple gem to greet users." # Short description
spec.description = "HelloGem is a minimal gem that greets users by name. Perfect for learning how to build Ruby gems!" # Longer than summary
spec.homepage = "https://github.com/your-username/hello_gem" # Link to your repo
spec.license = "MIT" # Common open-source license
spec.required_ruby_version = ">= 2.5.0" # Minimum Ruby version
# Prevent pushing the gem to a private repo accidentally
spec.metadata["allowed_push_host"] = "https://rubygems.org"
# Include only files tracked by Git (avoids including junk)
spec.files = Dir.chdir(File.expand_path(__dir__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
# Development dependencies (for testing, documentation, etc.)
spec.add_development_dependency "bundler", "~> 2.0"
spec.add_development_dependency "rspec", "~> 3.0" # For testing
end
Key Fields Explained:
spec.name: Must be unique on RubyGems.org. Check availability by searching RubyGems.org.spec.version: Pulls the version fromlib/hello_gem/version.rb.spec.files: Usesgit ls-filesto include only files tracked by Git (avoids including logs or temp files).spec.add_development_dependency: Dependencies needed to develop the gem (e.g., RSpec for testing). Users won’t install these.
Testing Your Gem
Testing ensures your gem works as expected. We’ll use RSpec, a popular Ruby testing framework.
Step 1: Install Development Dependencies
Your gemspec already includes rspec as a development dependency. Install it with:
bundle install
Step 2: Write Tests
Open spec/hello_gem_spec.rb and add tests for the greet method:
# spec/hello_gem_spec.rb
require "spec_helper"
RSpec.describe HelloGem do
describe ".greet" do
it "greets the world by default" do
expect(HelloGem.greet).to eq("Hello, World!")
end
it "greets a custom name" do
expect(HelloGem.greet("Alice")).to eq("Hello, Alice!")
end
end
end
Step 3: Run Tests
Execute the tests with:
bundle exec rspec
You should see output like:
..
Finished in 0.001 seconds (files took 0.089 seconds to load)
2 examples, 0 failures
If tests pass, your gem is working!
Building the Gem
Now that your code and tests are ready, package the gem into a .gem file.
Step 1: Build the Gem
Run:
gem build hello_gem.gemspec
This creates a file like hello_gem-0.1.0.gem in your project root.
Step 2: Test the Local Gem
Before publishing, install the gem locally to verify it works:
gem install ./hello_gem-0.1.0.gem
Now test it in irb (Ruby’s interactive console):
irb
require "hello_gem"
HelloGem.greet # => "Hello, World!"
HelloGem.greet("Bob") # => "Hello, Bob!"
exit
If it works, you’re ready to publish!
Publishing to RubyGems.org
Publishing makes your gem available to anyone with RubyGems.
Step 1: Log In to RubyGems
If you haven’t already, log in to your RubyGems account:
gem signin
Enter your RubyGems username and password when prompted.
Step 2: Push the Gem
Upload your .gem file to RubyGems.org:
gem push hello_gem-0.1.0.gem
You’ll see output like:
Pushing gem to https://rubygems.org...
Successfully registered gem: hello_gem (0.1.0)
Step 3: Verify Publication
Visit RubyGems.org and search for your gem (e.g., “hello_gem”). You should see your gem’s page with details from the gemspec.
Updating Your Gem
To fix bugs or add features, update your gem:
- Update the code in
lib/hello_gem.rb. - Bump the version in
lib/hello_gem/version.rb(e.g.,0.1.0→0.1.1for a bug fix). - Update tests in
spec/hello_gem_spec.rb. - Rebuild the gem:
gem build hello_gem.gemspec. - Push the new version:
gem push hello_gem-0.1.1.gem.
Conclusion
You’ve built and published your first Ruby Gem! 🎉 This guide covered the basics, but there’s much more to explore—adding executables, integrating with APIs, or optimizing performance. Gems are a powerful way to share your Ruby skills with the world, so don’t stop here!