Gemってなに?実際に作って学んでみる
はじめに
こんにちは。新卒エンジニアのアアツです😃
LRM株式会社で開発チームに所属しています。
先日のRubyKaigiで、Gemに関するセッションをいくつか受けてきました。
当時の私が持っていたGemのイメージは、「Rubyのコードを支えてくれる機能の集合体」といった、やや曖昧なものでした。
けれど改めて考えてみると、「Gem ってそもそも何なんだろう?」という疑問がふと湧いてきたのです。
そんなとき、Zennで面白そうな記事を見つけました。
この記事を読んで、「Gem は自分でも作れるものなんだ!」と知り、目から鱗が落ちました。
それと同時に、「実際に作りながら学んでみたい」という気持ちが強くなり、いてもたってもいられなくなりました。
ということで今回は、上記の記事を参考にしつつ、実際に手を動かしながらGemの仕組みを学んでいくことにします。
Gemの正体を探りながら、ゼロから作ってみる体験記として、ぜひお付き合いください!
今回作成したhello_ruby_gems
は以下のページで公開していますので、よろしければ参考にしてください。
Gemとは
まず、Gemとは何か。
私自身が曖昧に捉えていたこの概念を明確にするために、Gemの公式ガイドブックを参考にしながら整理していきます。
Rubyのパッケージ
Gemとは、Rubyのパッケージ(またはライブラリ)のことです。
rails
やnokogiri
など、Rubyのコードを再利用可能な形にまとめたパッケージを指します。
これらのパッケージは、Rubyの公式リポジトリRubyGems.orgに公開されています。
一度ダウンロードしてしまえば、そのGemが提供する機能を自分のアプリケーション内で自由に使えるようになります。
Gemについての理解も深まったところで、いよいよ自分でGemを作っていきます!
実際にGemを作ってみる
環境
ruby 3.4.4
Bundler 2.6.9
2025年5月17日時点で最新のものを使用します。
実装の流れ
以下の流れで実装を進めていきます。
- Gemの雛形を作成
- メソッドを追加する
- メソッドの動作確認
- rspecを追加する
- gemspecの編集をする
- Gemをビルドする
- README.md ファイルを編集する
- Gemの動作確認
Gemの雛形を作成
下記コマンドを入力します。
今回はhello_ruby_gems
というgemを作っていきます。
$ bundle gem hello_ruby_gems
色々と質問されるので答えていきます。
聞かれた内容
- Do you want to generate tests with your gem?
- Do you want to set up continuous integration for your gem?
- Do you want to license your code permissively under the MIT license?
- Do you want to include a code of conduct in gems you generate?
- Do you want to include a changelog?
- Do you want to add a code linter and formatter to your gem?
今回は、テスト形式にrspec
を選択し、質問には全て「y」で回答しています。
全ての質問に答えると、Gemが作成されます💪
メソッドを追加する
Gemが作成されると、以下のファイルが作成されます。
require_relative "hello_ruby_gems/version"
module HelloRubyGems
class Error < StandardError; end
# Your code goes here...
end
ここに、「名前を渡すと挨拶を返す」メソッドを追加してみます。
module HelloRubyGems
class Error < StandardError; end
def self.greet(name = "world")
"Hello, #{name}!"
end
end
追加できました。
では、動作確認をしてみます。
メソッドの動作確認
以下のコマンドを入力し、ターミナル上でRubyのメソッドを実行してみます。
$ irb -I lib -r hello_ruby_gems
コマンドの説明
-I lib
:lib/
ディレクトリを$LOAD_PATH に追加
-r hello_ruby_gems
:require hello_ruby_gems
と同じ意味
上記のコマンドを実行すると、以下のように出力されます。
irb(main):001> HelloRubyGems.greet
=> "Hello, world!"
irb(main):002> HelloRubyGems.greet("Aatsu")
=> "Hello, Aatsu!"
これで、「名前を渡すと挨拶を返す」メソッドの追加ができました!
rspecを追加する
Gem作成時に、rspec
を選択した場合、以下の構成でディレクトリが作成されているはずです。
hello_ruby_gems/
├── lib/
├── spec/
│ ├── hello_ruby_gems_spec.rb ← ここにテストを書く
│ └── spec_helper.rb ← RSpecの設定
依存関係のインストール
$ bundle install
上記のコマンドで依存関係をインストールしていきます。
テストを書く
hello_ruby_gems_spec.rb
ファイルにテストを書いていきます。
RSpec.describe HelloRubyGems do
it "greets with a default name" do
expect(HelloRubyGems.greet).to eq("Hello, world!")
end
it "greets with a custom name" do
expect(HelloRubyGems.greet("michel")).to eq("Hello, michel!")
end
end
テストを実行する
$ bundle exec rspec
上記のコマンドを入力すると、テストを実行することができます。
テストの結果は以下の通りです。
HelloRubyGems
greets with a default name
greets with a custom name
Finished in 0.01151 seconds (files took 0.48912 seconds to load)
2 examples, 0 failures
結果を見てわかる通り、テストがpassしましたね👏
念の為テストがfailedになることも確認しておきましょう。
テストがfailedになることを確認する
rspecを以下のように修正してみます。
it "greets with a default name" do
expect(HelloRubyGems.greet).to eq("Hello, japan!") ← "world"を"japan"に変更
end
テストの結果は以下のようになります。
HelloRubyGems
greets with a default name (FAILED - 1)
greets with a custom name
Failures:
1) HelloRubyGems greets with a default name
Failure/Error: expect(HelloRubyGems.greet).to eq("Hello, japan!")
expected: "Hello, japan!"
got: "Hello, world!"
(compared using ==)
# ./spec/hello_ruby_gems_spec.rb:5:in 'block (2 levels) in <top (required)>'
Finished in 0.01369 seconds (files took 0.07286 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/hello_ruby_gems_spec.rb:4 # HelloRubyGems greets with a default name
failedになることを確認できました。
テストを元に戻しておきます。
gemspecの編集をする
gemspec
ファイルは、Gemの概要を説明するためのものです。
ここに書かれた内容がRubygems.org
やgem build
で使用されます。
gemspec
ファイルの中身は以下のようになっているはずです。
Gem::Specification.new do |spec|
spec.name = "hello_ruby_gems"
spec.version = HelloRubyGems::VERSION
spec.authors = ["Your Name"]
spec.email = ["you@example.com"]
spec.summary = "TODO: Write a short summary"
spec.description = "TODO: Write a longer description"
spec.homepage = "TODO: Put your gem's homepage here"
spec.license = "MIT"
# 省略...
end
今回は、Rubygems.org
には公開しないので、spec.authors = ["Your Name"]
やspec.email = ["you@example.com"]
、spec.homepage = "TODO: Put your gem's homepage here"
は削除して構いません。
※name、version、summary、descriptionは必須です。
ここまでできたら、いよいよGemをビルドしていきます。
Gemをビルドする
以下のコマンドで、Gemをビルドすることができます。
$ gem build hello_ruby_gems.gemspec
ビルドに成功すると、以下のように出力されます。
Successfully built RubyGem
Name: hello_ruby_gems
Version: 0.1.0
File: hello_ruby_gems-0.1.0.gem
また、出力結果からhello_ruby_gems-0.1.0.gem
ファイルが生成されていることがわかります。
このファイルが生成されたことにより、hello_ruby_gems
はGemとして利用可能になりました👏
README.md ファイルを編集する
READMEファイルとは、プロジェクトの「概要」や「使い方」「インストール手順」などをまとめた説明書のようなテキストファイルです。
Gemを公開した際に、他の人がhello_ruby_gems
を利用するための手順書を用意します。
Gemの説明や、インストール方法、使用方法などをmarkdown形式で事細かに書いていきます。
作成したREADME.md ファイルは以下のページから確認できます。
Gemの動作確認
Gemをインストールする
$ gem install ./hello_ruby_gems-0.1.0.gem
上記のコマンドを入力し、作成したGemをローカルにインストールします。
インストールに成功すると、以下のように出力されます。
Successfully installed hello_ruby_gems-0.1.0
1 gem installed
これで、Gemのインストールはできました👏
ターミナルで動作確認
$ irb
irb(main):001> require 'hello_ruby_gems'
=> true
irb(main):002> HelloRubyGems.greet("Aatsu")
=> "Hello, Aatsu!"
作成したGemが動作することがわかりました!
応用編
GitHub経由で読み込んでみる
作成したGemを、GemfileからGitHub経由で読み込んでみたいと思います。
Gemを利用したいプロジェクトに移動
$ cd ~/your_project_directory
上記のコマンドで、任意のディレクトリに移動します。
Gemfileに追記
移動先のプロジェクトで、Gemfileに以下の記述をします。
gem 'hello_ruby_gems', github: 'AatsuTakahashi/hello_ruby_gems'
bundle installを実行
$ bundle install
Bundler
がGitHubからhello_ruby_gems
のコードを取得して、プロジェクト内で使えるようにしてくれます。
さいごに
今回の学習を通じて、Gemの作成や公開は、想像していたよりもずっと簡単にできることがわかりました。また、Gemそのものへの理解も大きく深まったと感じています。
自作のGemを使って、普段の開発で感じている課題を解決していくのも、きっと面白いだろうと思いました。学んだことを活かして、次は実用性のあるGemをどんどん作っていきたいです。
ここまで読んでいただき、ありがとうございました。
ご質問やご感想がありましたら、お気軽にコメントしていただけると嬉しいです🙌
参考
Discussion