sci

最果て風呂

Ruby の Gem と Bundler を使ってみる

この記事に関連するお話です。

Ruby の開発版を使っていたので気付かなかったのですけれど、リリース版には gems/ 以下に bundled_gems として次のものが同梱されているのでした。

did_you_mean-1.2.0/  did_you_mean-1.2.0.gem
minitest-5.10.3/     minitest-5.10.3.gem
net-telnet-0.1.1/    net-telnet-0.1.1.gem
power_assert-1.1.1/  power_assert-1.1.1.gem
rake-12.3.0/         rake-12.3.0.gem
test-unit-3.2.7/     test-unit-3.2.7.gem
xmlrpc-0.3.0/        xmlrpc-0.3.0.gem

雛形の作成

sudo gem install bundle で bundler をインストールしてから bundle gem rbmto でプロジェクトの雛形を作成します。このときに 3 つの質問があるので、それぞれ minitest, y, n と答えました。

Creating gem 'rbmto'...
Do you want to generate tests with your gem?
Type 'rspec' or 'minitest' to generate those test files now and in the future. rspec/minitest/(none): minitest
Do you want to license your code permissively under the MIT license?
This means that any other developer or company will be legally allowed to use your code for free as long as they admit you created it. You can read more about the MIT license at http://choosealicense.com/licenses/mit. y/(n): y
MIT License enabled in config
Do you want to include a code of conduct in gems you generate?
Codes of conduct can increase contributions to your project by contributors who prefer collaborative, safe spaces. You can read more about the code of conduct at contributor-covenant.org. Having a code of conduct means agreeing to the responsibility of enforcing it, so be sure that you are prepared to do that. Be sure that your email address is specified as a contact in the generated code of conduct so that people know who to contact in case of a violation. For suggestions about how to enforce codes of conduct, see http://bit.ly/coc-enforcement. y/(n): n
      create  rbmto/Gemfile
      create  rbmto/lib/rbmto.rb
      create  rbmto/lib/rbmto/version.rb
      create  rbmto/rbmto.gemspec
      create  rbmto/Rakefile
      create  rbmto/README.md
      create  rbmto/bin/console
      create  rbmto/bin/setup
      create  rbmto/.gitignore
      create  rbmto/.travis.yml
      create  rbmto/test/test_helper.rb
      create  rbmto/test/rbmto_test.rb
      create  rbmto/LICENSE.txt
Initializing git repo in /Users/home/rbmto

プロジェクトの設定

まずは rbmto.gemspec の編集から。ほとんどの項目が埋まっていて、プロジェクトの名前と説明を書くだけな感じでした。

spec.summary     = %q{rbmto}
spec.description = %q{Ruby de Mojiretsu wo Tanjun ni Okikae masu.}

この状態でとりあえず rake test をしてみるとエラーに。起動された rake が /usr/bin/rake だったのが原因。gem install rake で新しいものをインストール。

プロジェクトの実装

lib/rbmto.rb に実装していきます。class ではなく module で書くみたい。今まで書いたものをコピペして次の工程へ。実は module ではダメで class に戻したのは秘密。

テストの記述

/test/rbmto_test.rb に書いていきます。python でのテストを修正する形で記述しました。Ruby では class を使ってオブジェクト指向的に書いてあるので、いささか悩みました。それが先に書いた module ではダメで class にしたというもの。

module はインスタンス生成能力が無いので、インスタンス変数を使っているこのプログラムには合わないということなのでしょう。また、インスタンス変数にアクセスできなかったので、attr_reader を設定し、外部ファイルへのパスを保持するためにクラス変数 @@ も使いました。

rake test でテストができます。何度も繰り返して pass するようにしました。テストを書いている時間の方が長かったような?

パッケージの作成

実行ファイルは exe に入れるみたい。参考にしているライブラリが書いていたので、自分も下記を追記することにしました。パスの一番先頭にカレントディレクトリの lib 追加してくれるみたい。

$LOAD_PATH.unshift File.expand_path("../lib", __dir__)

パスの関係は難しいですね。

gem build rbmto.gemspec でカレントディレクトリに rbmto-0.1.0.gem が生成され、sudo gem install rbmto-0.1.0.gem でグローバル環境にインストールされました。試しに irbrequire 'rbmto' とすると、ture が返ってきました!

これでライブラリまでは作成することができたけれども、実行コマンドを bin/ にインストールすることができない。どうすれば良いのだろう?

gemspec をいじるらしい。exe ディレクトリはすでに bindir = 'exe' のように設定されているので、spec.executables の部分だけを spec.executables = "rbmto" のように変更。これで /usr/local/bin/rbmto がインストールされるようになったけれども、何も言わない……。

エラーにすらならないことから気がついて、次の部分をコメントアウトすることで動くようになりました。

# if __FILE__ == $0
    main()
# end

GitHub からのインストール

あとは Git リポジトリから直接インストールすることができれば良いのだけれど、うまい手立てが見つからない。今のところは手動で次のようにしてやるしかなさそう?

git clone https://github.com/user_name/rbmto.git rbmto
cd rbmto
gem build rbmto.gemspec
sudo gem install rbmto

specific_install を使うと良いことがわかりました。

gem specific_install -l 'git://github.com/user_name/rbmto.git'

ローカルにインストールしたい場合は --user-install オプションが効かないので、

GEM_HOME=~/.gem/ruby/2.6.0 gem specific_install -l https://github.com/user_name/rbmto.git

のように一時的に環境変数を指定してやると良いようです。