はじめての自作Gem - シンプルなGemを作成して公開する

# はじめに
社内勉強会でRuby Gemについて勉強しました。その復習を兼ねて自身でGemを作りながら、Gemの作り方について書いていこうと思います。かなりシンプルな実装になるので、だいたい30分ぐらいで作れると思います。※事前準備に必要な時間は入れていないです。

ちなみに私の環境です。

```sh
Ruby version 2.6.3
Bundler version 2.0.2
```

# Gemの作り方
### 事前準備

事前に以下の準備が必要です。

- Githubに今回作るGemのソースコードを置くための新しいリポジトリを作成
- RubyGemsのアカウント登録
- Bundler
    - bundle -v をして`Bundler version 1.9.0`未満の場合、`gem update bundler`してください。

### Gemのベースを作成する

Bundlerを使って作成します。Bundler無しでもGemの作成はできますが、現在はBundlerを使うのがスタンダードのような雰囲気があります。

`bundle gem gem_name`で簡単にGemのベースを作成できます。

HelloWorldでも良いのですが、今回は某有名俳優をリスペクトしたGemを作っていこうと思います。

```sh
$ bundle gem fujitatsu

# 同じ名前のGemをRubyGemsにアップロードすることはできないので、適宜名前は変えてください。
```

`bundle gem`コマンドを初めて使う場合は、テストをRSpecとminitestどちらで書くか、CODE_OF_CONDUCT.mdとLICENSE.txtを作っていいかを確認されます。

「テストをRSpecとminitestどちらで書くか」は慣れている方を選択すれば良いと思います。私はRSpecを選択しています。
「CODE_OF_CONDUCT.mdとLICENSE.txtを作っていいか」はYESで良いと思います。

- CODE_OF_CONDUCT.md
  - gemへのすべての貢献者が従うことを期待する行動規範を提供します。
- LICENSE.txt
  - [MITライセンス](https://ja.wikipedia.org/wiki/MIT_License)が含まれています。

```sh 
$ cd  fujitatsu
$ tree
.
├── CODE_OF_CONDUCT.md
├── Gemfile
├── Gemfile.lock
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
│   ├── console
│   └── setup
├── fujitatsu.gemspec
├── lib
│   ├── fujitatsu
│   │   └── version.rb
│   └── fujitatsu.rb
└── spec
    ├── fujitatsu_spec.rb
    └── spec_helper.rb
```

### gemspecを修正する
gem_name.gemspecにはメタデータが定義されています。書き直すべきところは、TODOと書かれているので、これを修正していきます。修正しないと`bundle install`をしたときに怒られます。

```ruby:fujitatsu.gemspec
# 書き直すところを抜粋

# Gemの要約を書きます
spec.summary       = %q{TODO: Write a short summary, because RubyGems requires one.}

# Gemの説明を書きます
spec.description   = %q{TODO: Write a longer description or delete this line.}

# ホームページURL or GithubのリポジトリURLを書きます。
spec.homepage      = "TODO: Put your gem's website or public repo URL here."

# https://rubygems.orgを書きます
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"

# GithubのリポジトリURLを書きます。
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."

# CHANGELOG.mdのURLを書きます。
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
```

このファイルの下部にある次のコードは、依存しているGemが書かれています。
これはGemfileから読み込まれていますので、Gemを追加した場合はここに追記しています。

```ruby:fujitatsu.gemspec
spec.add_development_dependency "bundler", "~> 2.0"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.0"
```

修正が終わったら、依存gemをインストールします。

```sh
bundle install
```

### コードを書いていく

libディレクトリにコードを書いていきます！

```sh
touch lib/fujitatsu/translator.rb
```

```ruby:lib/fujitatsu/translator.rb
module Fujitatsu
  class Translator
    # 渡された文字列に対して、1文字ごとに濁点をつけて返す
    def self.shout(word)
      word.split('').join('゛') + '゛'
    end
  end
end
```
　
つぎに`fujitatsu/translator.rb`を読み込めるように`require`します。

```ruby:lib/fujitatsu.rb
require "fujitatsu/version"
require "fujitatsu/translator"

module Fujitatsu
  class Error < StandardError; end
  # Your code goes here...
end
```

### テストを書いていく

コードの品質を担保するためにテストを書きましょう。
Gemとして公開するなら、なおさら重要ですね。

今回テストはRSpecを使います。

```sh
mkdir spec/fujitatsu
touch spec/fujitatsu/translator_spec.rb
```

```ruby:spec/fujitatsu/translator_spec.rb
RSpec.describe Fujitatsu::Translator do
  it "入力した文字に濁点をつけて返す" do
    expect(Fujitatsu::Translator.shout("どうしてなんだよぉおお！！うわぁぁあああああああああああ")).to eql("ど゛う゛し゛て゛な゛ん゛だ゛よ゛ぉ゛お゛お゛！゛！゛う゛わ゛ぁ゛ぁ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛")
  end
end
```

```sh
# テストを実行してみる
$ bundle exec rspec spec

Fujitatsu::Translator
  入力した文字に濁点をつけて返す

Finished in 0.00275 seconds (files took 0.1878 seconds to load)
# テストが通った！
1 example, 0 failures
```

### 作ったGemを確認してみる 
`rake build`コマンドでpkgディレクトリにgemをbuildします。
buildが完了したらgem installをします。

```sh　
$ rake build
fujitatsu 0.1.0 built to pkg/fujitatsu-0.1.0.gem.
$ gem install pkg/fujitatsu-0.1.0.gem
```
　
installができたら、irbを起動して、試してみましょう。

```sh
$ irb
```

```ruby

irb(main):002:0> require "fujitatsu"
=> true

irb(main):003:0> Fujitatsu::Translator.shout "どうしてなんだよおおおおおおお"
=> "ど゛う゛し゛て゛な゛ん゛だ゛よ゛お゛お゛お゛お゛お゛お゛お゛"
```

良い感じです！！！

### RubyGemsにアップロードする
`rake release`コマンドでアップロードできます。

※事前にRubyGemsのアカウントを登録して、[プロフィール編集ページ](https://rubygems.org/profile/edit)から`~/.gem/credentials`ファイルを作成してください。

```sh
$ rake release
```

### 実際にできたもの
- https://github.com/harashoo/fujitatsu
- https://rubygems.org/gems/fujitatsu

# 最後に
- Gemは簡単に作れることがわかったと思います！私の目標でもありますが、次は他の人にも使ってもらえるようなGemを作っていきたいですね！

- `gem fujitatsu`も機能を充実させていきたい。
    - 濁点をつける実装を丁寧にする。（漢字や数字には濁点をつけないなど）
    - 濁点をつけるだけでなく、セリフっぽく言い換えることができるようにする。

# 参考
- [MAKE YOUR OWN GEM](https://guides.rubygems.org/make-your-own-gem/)
- [How to create a Ruby gem with Bundler](https://bundler.io/v2.0/guides/creating_gem.html)