せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】パーフェクトRuby 学習感想文 ~余談:gem の秘密

gemって不思議だ、を詳しくみていきます。

(参考・経緯など)
パーフェクトRuby 学習感想文 ~はじめに


 

bundle はbundlerパッケージで定義されている

インストールされているgem を確認する

C:\>gem list

*** LOCAL GEMS ***

activemodel (3.2.14)
activerecord (3.2.14)
activesupport (3.2.14)
arel (3.0.2)
bigdecimal (1.2.0)
builder (3.0.4)
bundler (1.3.5)
diff-lcs (1.2.4)
gem_sample_pruby (0.0.1) …

なるほど。「bundler」ってパッケージが入ってるんだ。
だから

C:\>bundle
Bundler::GemfileNotFound

って、[bundle]コマンドを直接たたいても実行できるんだ
(今は引数渡してないからエラーになったけど)


 

コマンド名で実行できるもの

なんで

C:\>todo_samp -v

とか

C:\>bundle

って、コマンド名を直接たたいて実行できるんだ?
何が実行されてるんだ?

もう一度gemの章を見返してみる。
15章も見返してみる。

本には言及されていないけれど、
gemパッケージ/bin/[gemパッケージ名]
のファイルに書いてあるコードが実行されるようだ。

このファイルについての言及は本にはない(と思う。見つけられなかった)。

 
唯一、15章P555 にはこう書いてある

これ(コマンドライン引数)を、bin/todoからCommandクラスに渡すようにしましょう

~~サンプルコード~~

全く持って、bin/todoというファイルがなぜ出てきたのか疑問だったけれど、
このファイルには、コマンド名を直接たたいて実行される処理を書くようだ。

ためしにbundlerパッケージの中身も確認してみよう

■Ruby200\lib\ruby\gems\2.0.0\gems\bundler-1.3.5\bin\bundle

require 'bundler/cli'
require 'bundler/friendly_errors'
Bundler.with_friendly_errors { Bundler::CLI.start }

コードの意味は分からないけど、確かにここでCLIアプリケーションを開始させているぞ。


デフォルトgemパッケージのbin/[パッケージ名]の中身

$ bundle gem gem_test
      create  gem_test/Gemfile
      create  gem_test/Rakefile
      create  gem_test/LICENSE.txt
      create  gem_test/README.md
      create  gem_test/.gitignore
      create  gem_test/gem_test.gemspec
      create  gem_test/lib/gem_test.rb
      create  gem_test/lib/gem_test/version.rb

binフォルダがない?!!


ひょっとして。。。

$ bundle gem gem_test -b
   identical  gem_test/Gemfile
   identical  gem_test/Rakefile
   identical  gem_test/LICENSE.txt
   identical  gem_test/README.md
   identical  gem_test/.gitignore
   identical  gem_test/gem_test.gemspec
   identical  gem_test/lib/gem_test.rb
   identical  gem_test/lib/gem_test/version.rb
      create  gem_test/bin/gem_test

出来た!
なるほど。 P439の、

「-b」を渡すと、実行可能なコマンドの雛形を一緒に生成してくれます。

というのはこういう意味だったのか。

中身を見てみよう。

#!/usr/bin/env ruby

require 'gem_test'

中はこれだけか。

適当にコードを書いてみよう。

#!/usr/bin/env ruby

require 'gem_test'

p "kaitemitayo"

ビルドして、インストールしてみよう。

$ rake install
gem_test 0.0.1 built to pkg/gem_test-0.0.1.gem.
gem_test (0.0.1) installed.

SEKAI /c/repositories/gem_test (master)
$ gem_test
"kaitemitayo"

うわー。なるほど。

コマンドプロンプトにパッケージ名を直接打ったときは
bin内のファイルコードが実行されるんだ


ちょっとgemが分かったぞ。