Rubygemsのgemを $HOME/ 下へインストールしたくてハマった

Cloud Foundryのツール vmc がgemsでインストールするもので,さらに「まぁシステムワイドにやることでもなかろう」とか余計なことを思って普段と違うやり方に手を出してはまったと.はまっていた問題は,

  1. ~/.gemrcgemhome: /home/nodakai/.gems とか書いて
  2. gem install uuidtools (←なんでもいい.とりあえず依存のない小さなライブラリを例に挙げた)とかやると,
  1. gemhome のディレクトリ)/gems/uuidtools-2.1.2 は確かに作られるし
  2. gem list にリストアップされるのだが,
  3. いざ使いたいときに require しようとすると見つからない

というもの.つまり ruby -rubygems "require 'uuidtools'" が失敗した.
解は超単純で,環境変数 GEM_HOME を設定するだけで良かった.つまり上の gemhome の代わりに ~/.profile にこう書くだけ:

export GEM_HOME=$HOME/.gems

してみれば gemhome は何なんだ? custom_require.rb が見ないなら存在意義ねーだろ.(strace -e open ruby -rubygems "require 'uuidtools'" とかやって気づいた.なおここで環境変数 RUBYLIB をいじるのは無意味.どうせライブラリの実体はバージョン番号付きのディレクトリに入るので,Rubygems付属の(つまり -rubygems でロードされる custom_require.rb で差し替えられた後の)require に頼らなければ読み込みは不可能である.
最初,古い情報に従って「(gemhome のディレクトリ)/lib/uuidtools 等が作られるはず」と思っていて,だから「(gemhome のディレクトリ)/libRUBYLIB に追加設定しないと require できない & require 失敗はその辺りのせい」と思いこんでいたので,かなりの時間を無駄にした.辛い.
ああそう,現状では単に gem install--user-install を追加するのとほとんど変わりない.こっちでもよかったかもしれぬ... 環境変数 GEM_HOME による方法は差し替えがやりやすいという利点があるのだが,そういう妙に凝った考えを持つからはまるんだよな.

$ ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
$ gem env
RubyGems Environment:
  - RUBYGEMS VERSION: 1.8.15
  - RUBY VERSION: 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
  - INSTALLATION DIRECTORY: /home/nodakai/.gems
  - RUBY EXECUTABLE: /usr/bin/ruby1.8
  - EXECUTABLE DIRECTORY: /home/nodakai/.gems/bin
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-linux
  - GEM PATHS:
     - /home/nodakai/.gems
     - /home/nodakai/.gem/ruby/1.8
     - /var/lib/gems/1.8
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :benchmark => false
     - :backtrace => false
     - :bulk_threshold => 1000
     - "install" => "--no-ri --no-rdoc"
     - "update" => "--no-ri --no-rdoc"
  - REMOTE SOURCES:
     - http://rubygems.org/
$ gem list

*** LOCAL GEMS ***

addressable (2.2.8)
interact (0.4.3)
json_pure (1.6.7)
mime-types (1.18)
rb-readline (0.4.2)
rest-client (1.6.7)
rubyzip (0.9.8)
terminal-table (1.4.5)
uuidtools (2.1.2)
vmc (0.3.18)
$ gem list -d uuidtools

*** LOCAL GEMS ***

uuidtools (2.1.2)
    Author: Bob Aman
    Rubyforge: http://rubyforge.org/projects/uuidtools
    Homepage: http://uuidtools.rubyforge.org/
    Installed at: /home/nodakai/.gems

    UUID generator
$ echo $GEM_HOME
/home/nodakai/.gems
$ cat ~/.gemrc
install: --no-ri --no-rdoc
update: --no-ri --no-rdoc
$ ls $GEM_HOME
bin/  cache/  doc/  gems/  specifications/
$ ls $GEM_HOME/gems
addressable-2.2.8/  interact-0.4.3/  json_pure-1.6.7/  mime-types-1.18/  rb-readline-0.4.2/  rest-client-1.6.7/  rubyzip-0.9.8/  terminal-table-1.4.5/  uuidtools-2.1.2/  vmc-0.3.18/
$ ls $GEM_HOME/bin
restclient*  vmc*
$ strace -e open ruby -rubygems -e "require 'uuidtools'; p UUIDTools::UUID.timestamp_create" 2>&1 | uniq
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/usr/lib/libruby1.8.so.1.8", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libcrypt.so.1", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
open("/dev/urandom", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/ubygems.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/defaults.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/rbconfig.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/deprecate.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/exceptions.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/specification.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/version.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/requirement.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/version.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/deprecate.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/platform.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/deprecate.rb", O_RDONLY) = 3
open("/etc/localtime", O_RDONLY)        = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/path_support.rb", O_RDONLY) = 3
open("/var/lib/gems/1.8/specifications", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
open("/home/nodakai/.gem/ruby/1.8/specifications", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/nodakai/.gems/specifications", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
open("/home/nodakai/.gems/specifications/rb-readline-0.4.2.gemspec", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/dependency.rb", O_RDONLY) = 3
open("/usr/lib/ruby/vendor_ruby/1.8/rubygems/requirement.rb", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/rest-client-1.6.7.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/addressable-2.2.8.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/rubyzip-0.9.8.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/interact-0.4.3.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/vmc-0.3.18.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/terminal-table-1.4.5.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/json_pure-1.6.7.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/uuidtools-2.1.2.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/specifications/mime-types-1.18.gemspec", O_RDONLY) = 3
open("/home/nodakai/.gems/gems/uuidtools-2.1.2/lib/uuidtools.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/common.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/generic.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/common.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/ftp.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/generic.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/http.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/generic.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/https.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/http.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/ldap.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/generic.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/ldaps.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/ldap.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/mailto.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/uri/generic.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/time.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/parsedate.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/date/format.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/rational.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/thread.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/thread.so", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/digest/sha1.so", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/digest.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/digest.so", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/digest/md5.so", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/digest.rb", O_RDONLY) = 3
open("/home/nodakai/.gems/gems/uuidtools-2.1.2/lib/uuidtools/version.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/securerandom.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/openssl.so", O_RDONLY) = 3
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/usr/lib/x86_64-linux-gnu/libssl.so.1.0.0", O_RDONLY) = 3
open("/usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0", O_RDONLY) = 3
open("/usr/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/digest.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl/bn.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl/cipher.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl/config.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/stringio.so", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl/digest.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl/pkcs7.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl/ssl-internal.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/openssl/buffering.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/fcntl.so", O_RDONLY) = 3
open("/usr/lib/ssl/cert.pem", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/ruby/1.8/openssl/x509-internal.rb", O_RDONLY) = 3
open("/usr/lib/ruby/1.8/x86_64-linux/rbconfig.rb", O_RDONLY) = 3
--- SIGCHLD (Child exited) @ 0 (0) ---
open("/dev/urandom", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 3
#<UUID:0x3fb7a8ded4d4 UUID:e6ddaa00-acce-11e1-8b7a-00012ebc147b>