HelloworldなGemを作る

#HelloworldなGemを作る

##環境
ruby 2.1.9
gem  2.7.6
openSUSE

##概要
勉強の一環としてHelloworldなGemの作り方を学びました。
その時のことを忘れないために備忘録として投稿します。

### bundlerのインストール
Gemを作成する際にbundlerが必要になるのでインストールします。

openSUSEを使っていてruby2.1を使っている人は下記のzypperコマンドでbundlerが使えるようになります。

```console
zypper in ruby2.1-rubygem-bundler
```

それ以外の人は、下記のコマンドで出来ると思います(多分)。

```console
gem install bundler
```

### 雛形の作成

適当に勉強用のディレクトリを作成して下記のコマンドを打ち込んで雛形を作成しましょう。
gem_helloworldディレクトリが新たに作成され、その中にファイルがもりもりできます。

```console
bundle gem gem_helloworld
```

```console:出力
Creating gem 'gem_helloworld'...
Code of conduct enabled in config
MIT License enabled in config
      create  gem_helloworld/Gemfile
      create  gem_helloworld/.gitignore
      create  gem_helloworld/lib/gem_helloworld.rb
      create  gem_helloworld/lib/gem_helloworld/version.rb
      create  gem_helloworld/gem_helloworld.gemspec
      create  gem_helloworld/Rakefile
      create  gem_helloworld/README.md
      create  gem_helloworld/bin/console
      create  gem_helloworld/bin/setup
      create  gem_helloworld/CODE_OF_CONDUCT.md
      create  gem_helloworld/LICENSE.txt
      create  gem_helloworld/.travis.yml
      create  gem_helloworld/.rspec
      create  gem_helloworld/spec/spec_helper.rb
      create  gem_helloworld/spec/gem_helloworld_spec.rb
Initializing git repo in /home/kashiwara/勉強/ruby/gem作成/gem_helloworld
```

### gemspecファイルに関して
上の項目でgem_helloworld.gemspecというファイルが生成されたかと思います。
このgemspecファイルは、Gemを作る上にあたって必要不可欠なファイルであり、知らないと
詰むので情報をまとめます。

gemspecファイルの中身を見てみます。

```console
cat gem_helloworld.gemspec
```

```ruby:gem_helloworld.gemspec
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'gem_helloworld/version'

Gem::Specification.new do |spec|
  spec.name          = "gem_helloworld"
  spec.version       = GemHelloworld::VERSION
  spec.authors       = ["TODO: Write your name"]
  spec.email         = ["TODO: Write your email address"]

  spec.summary       = %q{TODO: Write a short summary, because Rubygems requires one.}
  spec.description   = %q{TODO: Write a longer description or delete this line.}
  spec.homepage      = "TODO: Put your gem's website or public repo URL here."
  spec.license       = "MIT"

  # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
  # delete this section to allow pushing this gem 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 { |f| f.match(%r{^(test|spec|features)/}) }
  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.10"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec"
end
```

gem specファイルには、gemに関する情報を書きます。
その情報を下記にまとめました。

| spec.○○○　                | 記述内容　　　　                         |
|:--------------------------|:---------------------------------------|
| name                      |gemの名前                                |
| version                   |gemのバージョン                           |
| authors                   |gem作成者の名前                           |
| email                     |作成者のメールアドレス                     |
| summary                   |gemの簡単な説明                           |
| description               |gemの細かい説明                           |
| homepage                  |gemの関連ページのURL                      |
| license                   |gemのライセンス                           |
| metadata                  |pushするホストの制限                    　 |
| files                     |gemパッケージに含む対象となるファイルリスト  |
| bindir                    |実行可能コマンドとしてのファイルのpath      |
| executables               |実行可能コマンドとしてのファイルリスト       |
| require_paths             |ロードパス                                |
| add_development_dependency|gemパッケージの依存関係の指定               |

※実行可能コマンド関連は、コマンドラインから実行できるgemを想像したらわかりやすいです。
kaminariとか、deviseとか、rspecとか(間違ってたらすいません)

### gemspecファイルの編集
gemspecファイルをいじります。
「TODO」をすべて削除して適当に入力していきます。
「TODO」が残ったままならビルドするときにエラーになるので注意してください。

```ruby:gem_helloworld.gemspec
# coding: utf-8                                                                                                                                                                                 
lib = File.expand_path('../lib', __FILE__)                                                                                                                                                      
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)                                                                                                                                         
require 'gem_helloworld/version'                                                                                                                                                                
                                                                                                                                                                                                
Gem::Specification.new do |spec|                                                                                                                                                                
  spec.name          = "gem_helloworld"                                                                                                                                                         
  spec.version       = GemHelloworld::VERSION                                                                                                                                                   
  spec.authors       = ["Kashiwara"]                                                                                                                                                            
  spec.email         = ["tekitou@mail.com"]                                                                                                                                                     
                                                                                                                                                                                                
  spec.summary       = %q{"hello world gem"}                                                                                                                                                    
  spec.description   = %q{"hello world  gem is for practice by me"}                                                                                                                             
  spec.homepage      = ""                                                                                                                                                                       
  spec.license       = "MIT"

  # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
  # delete this section to allow pushing this gem to any host.
  if spec.respond_to?(:metadata)
    spec.metadata['allowed_push_host'] = "'"
  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 { |f| f.match(%r{^(test|spec|features)/}) }
  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.10"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec"
end
```

### gemパッケージを作成する
実際にコードを書いていきます。Hello world Gemの内部を作りましょう。
libディレクトリに移動します。一応libディレクトリの場所を載せておきます。

```console
pwd
```

```console:出力
/home/kashiwara/勉強/ruby/gem作成/gem_helloworld/lib
```
移動したら、その中にgem_helloworld.rbというファイルがあると思います。
そのファイルがHello world Gemの内容を記述するファイルとなります。

私が書いたコードを以下に記します。

```ruby:gem_helloworld.rb
require "gem_helloworld/version"

module GemHelloworld
  class << self
    def hello_world
      puts "Hello world!!!!!!!!!"
    end
    
    def hello_world2
      puts "Hello world????????"
    end
  end
end
```

このコードに特に意味はありません。検証用です。

### gemのインストール
さきほど書いたコードをビルドします。
gem_helloworldディレクトリ内で下記のコマンドを打ち込んで下さい。

```console
rake build
```
成功したらpkgディレクトリが作成され、その中にgemパッケージのバイナリファイルが生成されます。

次に、gemのインストールをします。下記のコマンドを打ち込んで下さい。

```console
gem install pkg/gem_helloworld-0.1.0.gem 
```
```console:出力
Successfully installed gem_helloworld-0.1.0
Parsing documentation for gem_helloworld-0.1.0
Done installing documentation for gem_helloworld after 0 seconds
1 gem installed
```

ちゃんと入ったのか見てみます。

```console
gem list | grep "hello"
```

```console:出力
gem_helloworld (0.1.0)
```
入ってました。よかった。

### 実際に使ってみる
使えるのかどうか確かめてみます。
適当な場所で、下記のコード作成して実行してみました。

```ruby:test.rb
require 'gem_helloworld'

GemHelloworld.hello_world
GemHelloworld.hello_world2
```

```console:出力
Hello world!!!!!!!!!
Hello world????????
```

成功です。HelloworldなGemはこれで終わりです。

### 今後の予定
自分の技術力向上のために何か一つGemを作って公開したいと思います。
できたら、実用的なのにします。