RubyGems の落とし穴
                              RubyGems traps


                                西山和広




Powered by Rabbit 0.6.1
agenda
   rescue LoadError
      gettext の場合

      reliable-msg の場合


   インストールが遅い場合

   Debian の rubygems

   gem のインストール場所

   gem と実行ファイル
                         1/24
rescue
LoadError
rescue LoadError
   rubygems が require を置き換え
     require で読み込めない → LoadError を期待

     違う例外 Gem::Exception が発生




                                       3/24
gettext
 の場合
gettext の場合 (1)

     % ruby -rubygems -e '
     require "gettext"
     # ...
     begin
       require "gettext/rgettext" # 1.93.0
     rescue LoadError
       require "gettext/tools/rgettext" # 2.0.4
     end'
     .../rubygems.rb:258:in `activate': can't activate
     gettext (= 1.93.0, runtime) for [], already activated
     gettext-2.0.4 for [] (Gem::Exception)
       from .../rubygems/custom_require.rb:35:in `require'
       from -e:4



  po ファイル関連の部分を 2.0.4 対応していて発生
                                                             5/24
gettext の場合 (2)
  解決方法
    同時に対応する必要がないので新しい方だけ対応にして解決

    対応している Rails のバージョンも違うので別ブランチで




                                     6/24
reliable-
msg の場合
reliable-msg の場合 (1)
   再現方法


     % ruby -rubygems -e '
     gem "rails", "= 2.3.2"
     require "reliable-msg"'
     .../rubygems.rb:258:in `activate': can't activate
     activerecord (= 2.1.2, runtime) for [], already activated
     activerecord-2.3.2 for ["rails-2.3.2"] (Gem::Exception)



   実際に問題が発生したときは ap4r 経由



                                                                 8/24
reliable-msg の場合 (2)
    問題発生場所

 reliable-msg-1.1.0/lib/reliable-msg/message-store.rb:


      # Make sure we have a MySQL library before creating this class,
      # worst case we end up with a disk-based message store. Try the
      # native MySQL library, followed by the Rails MySQL library.
      begin
          require 'mysql'
      rescue LoadError
          require 'active_record/vendor/mysql'
      end



    'active_record/vendor/mysql' が rails 2.2.x 以降にな
    いのが原因                                          9/24
reliable-msg の場合 (3)
   解決方法
    mysql を入れて解決

    モンキーパッチで解決

      ap4r-0.3.7 をリリースしました - kiwamu日記
      http://d.hatena.ne.jp/
      kiwamu/20090323/1237804171

      [ap4r-devel-ja] ap4r with rails 2.2.x or later のス
      レッド

    複数バージョンの gem を入れない

                                                     10/24
インストー
ルが遅い場
  合
インストールが遅い場合
運用環境など ri や rdoc が不要の場合
  gem install --no-ri --no-rdoc GEMNAME

  $HOME/.gemrc に


                   gem: --no-rdoc --no-ri



  を追加

  REE (Ruby Enterprise Edition) のインストール時
     一緒にインストールされる gem (rails など) は --no-rdoc --
                                              12/24
     no-ri で入る
Debian の
rubygems
Debian の rubygems (1)
   FHS の影響
     gem が /var/lib/gems に入る

     gem の実行ファイルに PATH が通っていない

        /var/lib/gems/1.8/bin に PATH を通すか

        /usr/local/bin とかに symlink


   詳細は README.Debian 参照



                                            14/24
Debian の rubygems (2)
   gem update --system は危険
      パッケージ管理を無視してファイルを置き換え

      以後のパッケージのアップデートなどに悪影響

      こわいので試してません


   apt-pinning を使う
      例: Debian/lennyで新しいRubyGemを使う http://
      d.hatena.ne.jp/nyaxt/20090614#1244955954


   ruby 自体を /opt 以下などに別途インストール
                                                 15/24
      例: Ruby Enterprise Edition をインストール
gem のイン
ストール場
    所
gem のインストール場所 (1)
  GEM_HOME 環境変数
    設定されていればそこに


  sudo をつけないと ~/.gem 以下に
    ruby 自体を ~/opt などに入れていれば別




                                17/24
gem のインストール場所 (2)
  ~/.gem 以下に入った場合の問題点
    gem uninstall GEMNAME だけだと消せない

       gem uninstall GEMNAME -i=$HOME/.gem/ruby/1.8

       .gem以下にインストールしてしまったgemの消し方
       http://d.hatena.ne.jp/
       Sixeight/20090618/1245292946

    gem cleanup でも消えない

       GEM_HOME=$HOME/.gem/ruby/1.8 gem cleanup



                                                  18/24
gem と実
行ファイル
gem と実行ファイル (1)
ヽ( ・∀・)ノくまくまー(2009-06-04): [Ruby] 本当は怖い
家庭の Rubygems http://wota.jp/ac/?
date=20090604#p01
パッケージのディレクトリに、


                       bin/ls



とか作って


            # foo.gemspec
            Gem::Specification.new do |s|
             s.executables = ["ls"]         20/24
gem と実行ファイル (2)
  ~/.gem 以下にインストールを推奨する記事
    Rubygemsパッケージとか $HOME/.gem 以下にインストールす
    るだろjk - Rubyistみたいな - Rubyist http://
    rubyist.g.hatena.ne.jp/
    from_kyushu/20090605/1244189125

    Rubygems に /usr/bin を触らせないためには gem をユーザー
    ディレクトリで運用する+ - きたももんががきたん。 http://
    d.hatena.ne.jp/kitamomonga/20090605/
    ruby_rubygems_bins_install_to_user_dir

    Standards: RubyGems Best Practice http://
    ujihisa.blogspot.com/2009/06/rubygems-best-
    practice.html
                                                  21/24
gem と実行ファイル (3)
  ~/.gem 以下にインストールした場合
    PATH を通すのを忘れずに



         PATH=$HOME/.gem/ruby/1.8/bin:$PATH




                                              22/24
gem と実行ファイル (3)
  複数バージョンの ruby を入れている場合
    --program-suffix=18

    ruby や irb は ruby18 や irb18

    gem で入れると全部 rake とか rails とか

    --format-executable

        rails18 や rails-1.8.7 に

        Standards: RubyGems Best Practice http://
        ujihisa.blogspot.com/2009/06/rubygems-best-
        practice.html
                                                      23/24
まとめ
               複数バージョンの gem は混ぜない
                          GEM_HOME で完全にわけるとか


               $HOME/.gemrc に


                               gem: --no-rdoc --no-ri --format-executable



               を追加 (おこのみで)

               パッケージ管理のファイルを壊さない
                          apt 管理下のファイルを勝手に壊さない                              24/24
Powered by Rabbit 0.6.1

RubyGemsの落とし穴

  • 1.
    RubyGems の落とし穴 RubyGems traps 西山和広 Powered by Rabbit 0.6.1
  • 2.
    agenda rescue LoadError gettext の場合 reliable-msg の場合 インストールが遅い場合 Debian の rubygems gem のインストール場所 gem と実行ファイル 1/24
  • 3.
  • 4.
    rescue LoadError rubygems が require を置き換え require で読み込めない → LoadError を期待 違う例外 Gem::Exception が発生 3/24
  • 5.
  • 6.
    gettext の場合 (1) % ruby -rubygems -e ' require "gettext" # ... begin require "gettext/rgettext" # 1.93.0 rescue LoadError require "gettext/tools/rgettext" # 2.0.4 end' .../rubygems.rb:258:in `activate': can't activate gettext (= 1.93.0, runtime) for [], already activated gettext-2.0.4 for [] (Gem::Exception) from .../rubygems/custom_require.rb:35:in `require' from -e:4 po ファイル関連の部分を 2.0.4 対応していて発生 5/24
  • 7.
    gettext の場合 (2) 解決方法 同時に対応する必要がないので新しい方だけ対応にして解決 対応している Rails のバージョンも違うので別ブランチで 6/24
  • 8.
  • 9.
    reliable-msg の場合 (1) 再現方法 % ruby -rubygems -e ' gem "rails", "= 2.3.2" require "reliable-msg"' .../rubygems.rb:258:in `activate': can't activate activerecord (= 2.1.2, runtime) for [], already activated activerecord-2.3.2 for ["rails-2.3.2"] (Gem::Exception) 実際に問題が発生したときは ap4r 経由 8/24
  • 10.
    reliable-msg の場合 (2) 問題発生場所 reliable-msg-1.1.0/lib/reliable-msg/message-store.rb: # Make sure we have a MySQL library before creating this class, # worst case we end up with a disk-based message store. Try the # native MySQL library, followed by the Rails MySQL library. begin require 'mysql' rescue LoadError require 'active_record/vendor/mysql' end 'active_record/vendor/mysql' が rails 2.2.x 以降にな いのが原因 9/24
  • 11.
    reliable-msg の場合 (3) 解決方法 mysql を入れて解決 モンキーパッチで解決 ap4r-0.3.7 をリリースしました - kiwamu日記 http://d.hatena.ne.jp/ kiwamu/20090323/1237804171 [ap4r-devel-ja] ap4r with rails 2.2.x or later のス レッド 複数バージョンの gem を入れない 10/24
  • 12.
  • 13.
    インストールが遅い場合 運用環境など ri やrdoc が不要の場合 gem install --no-ri --no-rdoc GEMNAME $HOME/.gemrc に gem: --no-rdoc --no-ri を追加 REE (Ruby Enterprise Edition) のインストール時 一緒にインストールされる gem (rails など) は --no-rdoc -- 12/24 no-ri で入る
  • 14.
  • 15.
    Debian の rubygems(1) FHS の影響 gem が /var/lib/gems に入る gem の実行ファイルに PATH が通っていない /var/lib/gems/1.8/bin に PATH を通すか /usr/local/bin とかに symlink 詳細は README.Debian 参照 14/24
  • 16.
    Debian の rubygems(2) gem update --system は危険 パッケージ管理を無視してファイルを置き換え 以後のパッケージのアップデートなどに悪影響 こわいので試してません apt-pinning を使う 例: Debian/lennyで新しいRubyGemを使う http:// d.hatena.ne.jp/nyaxt/20090614#1244955954 ruby 自体を /opt 以下などに別途インストール 15/24 例: Ruby Enterprise Edition をインストール
  • 17.
  • 18.
    gem のインストール場所 (1) GEM_HOME 環境変数 設定されていればそこに sudo をつけないと ~/.gem 以下に ruby 自体を ~/opt などに入れていれば別 17/24
  • 19.
    gem のインストール場所 (2) ~/.gem 以下に入った場合の問題点 gem uninstall GEMNAME だけだと消せない gem uninstall GEMNAME -i=$HOME/.gem/ruby/1.8 .gem以下にインストールしてしまったgemの消し方 http://d.hatena.ne.jp/ Sixeight/20090618/1245292946 gem cleanup でも消えない GEM_HOME=$HOME/.gem/ruby/1.8 gem cleanup 18/24
  • 20.
  • 21.
    gem と実行ファイル (1) ヽ(・∀・)ノくまくまー(2009-06-04): [Ruby] 本当は怖い 家庭の Rubygems http://wota.jp/ac/? date=20090604#p01 パッケージのディレクトリに、 bin/ls とか作って # foo.gemspec Gem::Specification.new do |s| s.executables = ["ls"] 20/24
  • 22.
    gem と実行ファイル (2) ~/.gem 以下にインストールを推奨する記事 Rubygemsパッケージとか $HOME/.gem 以下にインストールす るだろjk - Rubyistみたいな - Rubyist http:// rubyist.g.hatena.ne.jp/ from_kyushu/20090605/1244189125 Rubygems に /usr/bin を触らせないためには gem をユーザー ディレクトリで運用する+ - きたももんががきたん。 http:// d.hatena.ne.jp/kitamomonga/20090605/ ruby_rubygems_bins_install_to_user_dir Standards: RubyGems Best Practice http:// ujihisa.blogspot.com/2009/06/rubygems-best- practice.html 21/24
  • 23.
    gem と実行ファイル (3) ~/.gem 以下にインストールした場合 PATH を通すのを忘れずに PATH=$HOME/.gem/ruby/1.8/bin:$PATH 22/24
  • 24.
    gem と実行ファイル (3) 複数バージョンの ruby を入れている場合 --program-suffix=18 ruby や irb は ruby18 や irb18 gem で入れると全部 rake とか rails とか --format-executable rails18 や rails-1.8.7 に Standards: RubyGems Best Practice http:// ujihisa.blogspot.com/2009/06/rubygems-best- practice.html 23/24
  • 25.
    まとめ 複数バージョンの gem は混ぜない GEM_HOME で完全にわけるとか $HOME/.gemrc に gem: --no-rdoc --no-ri --format-executable を追加 (おこのみで) パッケージ管理のファイルを壊さない apt 管理下のファイルを勝手に壊さない 24/24 Powered by Rabbit 0.6.1