Ruby 1.8.7 與 Mac OS X 的地雷

Ruby 1.8.7 發行之後這麼久才升級,純粹是我沒注意到這件事。

1.8.7 有一些新功能是我覺得很有用的,其中包括 String 現在已經是 $KCODE-aware 的了 (僅管 $KCODE 在 1.9 已經是一個 deprecated 的全域變數,被一個叫作 Encoding 的 Class 給取代了)。考慮以下執行結果:

$ irb
irb(main):001:0> "的我他".chars.to_a
=> ["\347", "\232", "\204", "\346", "\210", "\221", "\344", "\273", "\226"]
irb(main):002:0> $KCODE='u'
=> "u"
irb(main):003:0> "的我他".chars.to_a
=> ["的", "我", "他"]
irb(main):004:0>

所以我前兩天就升級了,但沒想到卻踩到超級地雷。

我們知道 Mac OS X 自 10.5 開始內建 Ruby,它的版本是 1.8.6。

我們知道你如果要升級 Ruby 你必須要安裝 Xcode 和 MacPorts,接下來再透過 sudo port install ruby 的方式來「升級」,蘋果沒有提供 Binary Package。

……事實上,這樣並不是升級。

內建的 Ruby 安裝在 /System/Library/Frameworks/Ruby.framework ,你在 /usr/bin 裡面的 ruby, ri, rdoc 其實各是一個 Symbolic Link 指向 /System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ 裡面的執行檔。

而你透過 MacPorts 安裝的卻是放在 /opt/local/bin/ 裡面。

這有甚麼差呢?直接改 $PATH 不就好了?

不。因為 gem 是依存於 ruby 的安裝路徑的,所以,在不同路徑的 ruby ,所存取的 gem 是不同的。

因此,如果你跟我一樣,透過這種方式「升級」到 1.8.7,然後你又是在寫 Rails 的,你就會看到這個慘絕人寰的畫面:

$ ./script/console
Rails requires RubyGems >= . Please install RubyGems and try again: http://rubygems.rubyforge.org

噴掉就算了,連版本都沒寫,這是怎樣!

求救於 Google 大神,果然已經有先賢先烈了

怎麼辦呢?

首先咱們先把目前的 gem 清單備份下來,直接執行 gem list,把它顯示出來的東西複製起來貼到別的地方就行了。

接著,如果你不想改 $PATH 的話,直接把 /usr/bin/ 裡面的三個執行檔的 symbolic link 解掉,改連到 /opt/local/bin 裡面的:

$ cd /usr/bin
$ sudo rm ruby rdoc ri
$ sudo ln -s /opt/local/bin/ruby ruby
$ sudo ln -s /opt/local/bin/rdoc rdoc
$ sudo ln -s /opt/local/bin/ri ri

接下來重灌 rubygems,你沒看錯,是重灌

到這裡下載最新版的 rubygems,解壓縮之後, cd 進去那個解開來的路徑,然後 sudo ruby setup.rb ,就安裝好了。

裝完之後,當然也要改一下 /usr/bin 裡面的 link:

$ cd /usr/bin
$ sudo rm gem
$ sudo ln -s /opt/local/bin/gem gem

當然還沒好,我們說 gem 是依存於 ruby 的 path,所以你現在 gem list 看你的 Local Gems 一定是空的。

所以接下來就是把我們剛剛記下來的 gem list 裡面的東西裝回來啦。

不過基本上,你裝了 rails 就會順便裝以下的東西:

Successfully installed rake-0.8.4
Successfully installed activesupport-2.3.2
Successfully installed activerecord-2.3.2
Successfully installed actionpack-2.3.2
Successfully installed actionmailer-2.3.2
Successfully installed activeresource-2.3.2
Successfully installed rails-2.3.2

如果你要指定版本的話,例如你是用 2.2.2 的 rails 寫 Ruby on Rails 的程式,但你不指定版本的話會裝到最新版 2.3.2 (據說有若干功能上的出入),便是:

sudo gem i rails -v=2.2.2

如果你要掛 Proxy 的話(例如萬惡的臺灣帥範太學,連國外慢得跟烏龜一樣,這時候就要借助教育部的 HTTP Proxy),就在後面加參數:

sudo gem i rails -v=2.2.2 -p http://proxy.edu.tw:3128

套件可以一次裝完,我會用到的就這些:

sudo gem i passenger mongrel hpricot ruby-openid sqlite3-ruby capistrano will_paginate

然後注意一下,如果你的 Rails 是透過 Passenger 啟動的,重新安裝 Passenger 之後,要修改 /etc/apache2/httpd.conf 裡面關於 Passenger 執行檔的路徑。

照上述方式處理完之後,我的 script/console 就可以動了 (感動 Q___Q)

p.s. 如果你要安裝 mysql (Rails 的 ActiveRecord Adapter),直接 sudo gem i mysql 會噴掉。請參考這裡

關於 Chitsaou Yorkxin
From Taiwan, a National Taiwan Normal University undergraduate student major in Computer Science. You may call me Chitsaou :)

9 Responses to Ruby 1.8.7 與 Mac OS X 的地雷

  1. voglia 說道:

    超深奧
    其實你是神吧學長

    • Chitsaou Yorkxin 說道:

      不是的

      神的話會寫看不懂的語言

      我是用中文

  2. CFC 說道:

    Ruby 1.8.7不建議跑任何的Rails吧XD
    不信的話可以試試看Rails內建的Chars,保證噴啊啊啊!

    『喔買尬』.chars.size #=> 炸

    • Chitsaou Yorkxin 說道:

      Rails 2.3.2 支援 Ruby 1.8.7

      官方也建議用 1.8.7 這個版本

      我會用 1.8.7 是為了原文第一行所提及的那個功能

  3. CFC 說道:

    Rails 2.3.2應該是Ruby 1.9.1吧?
    我剛沒注意到是2.3.2,看成是2.2.2
    如果是2.2.2就真的不要用到Ruby 1.8.7 XD
    我個人推崇Ruby 1.9.1 + Rails 2.3.2
    So Nice!

    • Chitsaou Yorkxin 說道:

      是喔

      我自己是用 1.8.7 跑 Rails 2.2.2 到現在還沒出過問題

  4. CFC 說道:

    我是因為Project用Rails 2.2.2,跑在Ruby 1.8.7的Production server發現會炸的… Orz
    後來Upgrade到Ruby 1.9.1,炸得更慘
    只好Downgrade到Ruby 1.8.6

  5. JokerCatz 說道:

    去REE官方下載source
    解開用
    sudo ./installer –no-tcmalloc
    安裝,之後全數ln覆蓋即可,opt..ruby/bin/*到usr/bin下,like
    sudo ln -s -f /opt/ruby-enterprise-1.8.7-2009.10/bin/ruby /usr/bin
    沒那麼複雜的,&有需要的話來我們論壇坐坐:) 以上

    • Chitsaou Yorkxin 說道:

      thanks, but I prefer MacPorts :)

發表迴響

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>