gemの作り方
OIC ITCreate Club 第一 Advent Calendar 2017、22日目担当t-kusakabeです。
今回はRubyでgemを作ってみようと思います。
環境
ruby:2.4.2を使います。
bundlerをinstallしておいてください。
gem install bundler
まずは雛形
gem_sample という名前で作っていくことにします。
bundle gem gem_sample -t
以下の雛形が出来上がります。
.
├── Gemfile
├── README.md
├── Rakefile
├── bin
│ ├── console
│ └── setup
├── gem_sample.gemspec
├── lib
│ ├── gem_sample
│ │ └── version.rb
│ └── gem_sample.rb
└── spec
├── gem_sample_spec.rb
└── spec_helper.rb
gemの説明を追記
gem_sample.gemspecを編集してください。
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "gem_sample/version"
Gem::Specification.new do |spec|
# gemの名前
spec.name = "gem_sample"
spec.version = GemSample::VERSION
spec.authors = ["t-kusakabe"]
spec.email = ["アドレス"]
# 概要を追記
spec.summary = %q{OIC ITCreate Club 第一 Advent Calendar 2017}
# 説明を追記
spec.description = %q{gemを作ってみる}
# homepageを追記
spec.homepage = "https://itc.moe/"
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
# to allow pushing to a single host or delete this section to allow pushing to any host.
if spec.respond_to?(:metadata)
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
else
raise "RubyGems 2.0 or newer is required to protect against " \
"public gem pushes."
end
spec.files = `git ls-files -z`.split("\x0").reject do |f|
f.match(%r{^(test|spec|features)/})
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.16.a"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.0"
end
実装してみる
ひとまず文字列を返す様にしてみます。
require "gem_sample/version"
module GemSample extend self
def hello
'Hello OIC ITCreate Club 第一 Advent Calendar 2017'
end
end
helloというメソッドを定義して、 'Hello OIC ITCreate Club 第一 Advent Calendar 2017' という文字列を返します。
実行してみる
ちゃんと文字列が返ってくるか確認してみます。
bundle
bundle exec irb
require 'gem_sample'
GemSample.hello
=> "Hello OIC ITCreate Club 第一 Advent Calendar 2017"
ちゃんと返ってきてくれました!
buildする
gem build gem_sample.gemspec
Successfully built RubyGem
Name: gem_sample
Version: 0.1.0
File: gem_sample-0.1.0.gem
buildが出来るとinstallが出来る様になります。
gem install gem_sample
Successfully installed gem_sample-0.1.0
Parsing documentation for gem_sample-0.1.0
Installing ri documentation for gem_sample-0.1.0
Done installing documentation for gem_sample after 0 seconds
1 gem installed
gemを公開してみる
せっかく作ったのでgemを公開してみます。
git add .
git commit -m 'init'
githubで適当にリポジトリを作成してください。
リポジトリはpublicで作成します。
(今回は 'git@github.com:t-kusakabe/gem_sample.git' を作成しました)
リモートリポジトリを登録します。
git remote add origin git@github.com:t-kusakabe/gem_sample.git
git push -u origin master
これで作ったgemを公開することができました!
実際に使ってみましょう。
cd ~/
mkdir test
cd test
bundle init
Gemfileを以下の様に書き換えます。
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'gem_sample'
編集後installします。
bundle
Fetching gem metadata from https://rubygems.org/.
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using bundler 1.16.0.pre.3
Using gem_sample 0.1.0
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
installできました!
最後に。
どうでしたでしょうか。
gemの作成は以外とハードルが低いので汎用性の高いものはgemにしてしまうのもありかもしれません。
個人的な感覚でいうと
複数の処理まとめたい
-> method化する
複数のmethodをまとめたい
-> module化する
-> class化する
他のところでも使いたい
-> gemにする
みたいな感じで良いかなーと思っています。
ただ最近だとgemをinstallしてからconfigいじったり使うまでに複雑な手順を必要するものもあったりするのでそういうのはgemにするべきではないなーとも思ったりしてます。
興味を持たれた方は是非gemを作ってみてください。