rvmを使ってREEへの移行を考える

Ruby Enterprise Edition が海外では人気らしいというのは知っていたけど、別に今のところ Rails 仕事なんてないしなとか悠長なことを考えていました。

Welcome — Ruby Enterprise Edition

RHEL クローンでは RubyEE は yum ですぐ使える

そんな中、RHEL 5 クローンな OS では yum で入る Ruby が 1.8.5 で、いやだなぁ、せめて 1.8.6 なら良かったのにと考えていたら以下の記事で

Ruby 1.8.6 Policy

いよいよ RubyGems も RDoc も Ruby 1.8.7 に絞りたいよんと言い始めました。さすがにこれはちょっと困ったなー、どうすっかなーと思っていたところ、先日 Ruby EE ( Enterprise Edition ) が 1.8.7 ベースになっていたことを偶然知り1、また

End Point Package Repository

で RHEL 5 用に Ruby EE を含むパッケージ群の yum レポジトリが用意されていることも知っていたし、

Twitter / poppen: centosにRubyEEとnginx + pass …

centosにRubyEEとnginx + passengerをインストールしたでござる

と、普段CentOSを使わない人の動向も知っていたので、間違いなくイケるぞと判断し、

こりゃあ Ruby EE に移行するしかない

と、ようやく思い立ったわけです。うーん前振りが長いな。

yum で RubyEE を入れる作業は省略

End Point のサイトに書いてある通りなので。自分の platform に合う repository データの rpm を入れるだけ。

2010-07-17 現在、i386 向けのものは

ruby-enterprise.i386 : Ruby Enterprise Edition (Release 20090520)

です。

RubyEE 移行への検証環境を rvm で作る

RVM: Ruby Version Manager - RVM Ruby Version Manager - Documentation

問題は RubyEE へすぐ移行できるかどうかです。少ないながらも Ruby のコード資産はあります。一応常用環境が 1.8.[67] なので新たに書いたコードは問題ないと思いますが、1.6 時代から使っているものはさすがに一通り検証してからでないとちょっと怖い。特に 1.8.7 は非互換の部分がちょいちょいあるので、意図せず踏んでいるケースが考えられます。

そうなると一気に yum で Ruby を抜いて Ruby EE を入れて gem を入れ直しておしまい、とはいきません。

どっかに検証環境を作らなきゃ。でも Ruby EE を手軽に入れられる環境は他にないな。

普段使っているプラットフォームは

  • OSX 10.5 + Fink Ruby 1.8.6
  • Debian 5.0.x + Ruby 1.8.7
  • CentOS 5.x + Ruby 1.8.5

で、問題はこの CentOS なわけですが、これを入れ替える前に RubyEE の検証を行いたいわけです。

やりやすいのは Debian に rvm 環境を作って rvm で RubyEE を入れる方法かなー、読んだことあるし。2

ということで今度は rvm のインストール。

rvm は bash スクリプトで install して動かす

※ Windows ? 知らないっす :-) 適当に VM で Linux 動かせばいいと思います。

入れ方は何通りかあるように見えますが、結局

bash スクリプト群を download して動かす

という方法には変わりありません。shebang に

#! /usr/bin/env bash

と書かれているので *BSD など bash の入ってない環境では先にインストールしてください。

自分が試したのは github から直接 download して動かす方法でしたが、rubygems からインストールしてる人もいるようですし、たぶんどっちでもうまくいきます。というのも、普通にユーザー権限でインストールしていく場合には rvm は

~/.rvm

で完結し、システムに用意されている Ruby と rvm でインストールした Ruby を明確に区別できるからです。そのために login shell の rc ファイルに

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"

を追加しろ、と書かれています。

つまり、そういうことです。基本的には rvm で入れる Ruby は他のユーザーには影響しませんし、何もケアしていない場合は shell を変えるだけで使えなくなります。

ビルドに必要なものをパッケージで用意

さて、rvm 自体は bash スクリプト群なので扱いも楽ですが、rvm で Ruby をインストールする作業は結局自分でコンパイルすることに他なりません。少なくとも RubyEE を rvm でインストールする際には以下のものを要求されるようです。

  • C Compiler
  • C++ Compiler
  • make
  • patch
  • zlib headers
  • openssl headers
  • readline headers

環境や入れる Ruby のバージョンによって要求されるものは当然違うと思いますが、これらをシステム標準のパッケージでインストールしてしまえば ok です。インストールがうまくいかない場合はカラフルな log を見ればたぶん分かります。実際この記事は log を開いて書いてます。–trace を使えばリアルタイムにも確認できるかもしれません。やってみてないですけど。

rvm でインストールした ruby の使い方

同じです。irb の prompt などは違いますし、インストール済みの gem も違いますが、動かし方は同じです。というか、何を起動しようとしているかによって違います。MRI にない JRuby 独自の動かし方などがあればそれに従います。

基本的な rvm サブコマンド

rvm use利用する Ruby を切り替える
rvm use –default指定のバージョンをデフォルトの Ruby とする

use –default を使えばシステム標準の Ruby がなくてもとりあえず開発はできるかもしれませんね。

ちなみに default は

~/.rvm/environment/

以下を見れば分かります。

default -> ~/.rvm/environments/ree-1.8.7-2010.02
ree-1.8.7-2010.02
ree-1.8.7-2010.02@global
ruby-1.9.2-rc2
ruby-1.9.2-rc2@global
system

こんな風になっています。system が何ともリンクしていないのはたぶん system の Ruby がないからです。

rvm listインストール済み Ruby の一覧
rvm list knownインストール可能な Ruby の一覧

2010-07-17 時点で Ruby 1.8.6 からしかインストールできないっぽいんですが、もう今のバージョンはそうなんですかね。昔のバージョンはもっと古いものも入れられたみたいですが。

rvm ruby SCRIPT指定の SCRIPT をインストール済みの全 ruby で実行
rvm VERSION,VERSION[, …] SCRIPT指定の SCRIPT を指定の VERSION の ruby で実行
rvm rubydefault の ruby で irb を立ち上げる

検証対象のコードをインストール済みの ruby で一気に実行することができます。いちいち rvm use で切り替える必要なし。 全 ruby じゃなくてコレとコレで実行したい、という指定もできますが、特定のバージョンでだけ実行することはできないようです3

その場合は rvm use して切り替えてから普通に

ruby SCRIPT

で実行すれば済む、ということでしょうね。

sudoして使いたい

Ruby スクリプトを純粋に Web アプリだけに使っているのならあまり関係しないかもしれませんが、システム管理に使っている場合は sudo で権限を変えて実行したい場合がよくあります。しかし、先に書いたように rvm でインストールした Ruby は基本的に自分の常用環境でしか動きません。

そこで rvmsudo というツールが用意されています。

~/.rvm/bin/rvmsudo

これで rvm でインストールした Ruby を sudo で使えます。

特定のディレクトリだけ違うバージョンを使いたい

これ! これめっちゃ便利そう。使い方は簡単、目的のディレクトリに

.rvmrc

というファイルを置き、中に Ruby のバージョンを指定するコマンドを書くだけ。例えば

rvm use 1.9.2

としておくと、この .rvmrc の置いてあるディレクトリ以下だけで Ruby 1.9.2 がデフォルトの Ruby になります。外からこのディレクトリに cd したときに Ruby が切り替わった旨のメッセージも出ます。

info: Using ruby 1.9.2 rc2

これはすごいなぁ。例えば特定の branch は特定のバージョンの Ruby 用です、ということをこのたった一つのファイルだけで明示できる。なんてこった!

※ 脱線しますが、こういうものこそ PHP に欲しいんですよねぇ。いい悪いでなく PHP では中小規模のものを扱うことが多いので、より多くの環境に対応できた方が嬉しいんです。でも基本的に mod_php だと OS ごと仮想化する形の方が結果的に面倒が少ないんです。とは言えやはり大げさなんですよねぇ。別に Apache のバージョンや OS のバージョンに依存してないのに全環境を仮想化しなきゃいけないのは。

まとめ

Ruby 1.9 移行期であり、また複数の Ruby 実装の完成度が急速に上がってきていますし、Ruby で開発を行う人には rvm はとても便利ですね。面倒そうで渋っていたけど、自分のスクリプトの portability も上げていかないといけないので Mac にも入れないとダメだなと思いました。(これ書いている時点ではまだ仮想環境でしか入れてないですけど。)

RubyEE はあえて歩みを遅くしたい場合に有効な選択肢で、RHEL クローンでは簡単にインストールできるのがとてもありがたいです。恐らく RHEL 系は想定以上の歩みの遅さに悩まされると思いますので、RubyEE を基本と考えるくらいでいいのかもしれません。

残った課題は

  • rvm で入れた Ruby 自体をシステム標準とする方法
    • そもそもこれにメリットがないといけないので、しばらくは放置かな?
  • bundler との組み合わせでも大丈夫になったらしい情報が rvm のサイトに書いてあるが、bundler 自体が分かっていない

なんとなく bundler こそ PHP に欲しい機能のはずだと思っているので、時間を見つけて try したいです。

参考

  1. チェックしていなかった 

  2. 幸いこの Debian は比較的速いマシンで動いているし。 

  3. 0.1.43で確認 

絵文字とかケータイ対応を調べてみた。想定は Apache + PHP

まぁこれも今さらなネタですが。

一つのアプリ、コンテンツから PC/ケータイ両対応したいことってよくありますな。そのための変換ツールを調べてみた。

ただし、最初に断っておくと以下のどれも採用していない。

Apache モジュールタイプ

Apache モジュールで画像を変換したり絵文字対応したりというアプローチはアプリの開発言語を選ばないので魅力的。

mod_ktai

  • yumemi
  • Apache License 2.0 と言っているがソースが公開されていないという指摘多数。
  • 企業開発なのでリソースが十分投入されていそうだけどとにかく評価できない

その後、なんでソース公開されていないの?という疑問に答えるようなアクションもないし、実はもう使ってないんじゃないか疑惑。

mod_chxj

  • 基本的に個人開発(確認時点ではメンバー3人)
  • ちゃんとオープンソース(Apache License 2.0)
  • 残念ながら参加も開発も活発な感じはしない

こういうツールって地味なので一人だとモチベーションを維持するのが大変だし、実際開発の停滞した時期もある。もしかすると github に置いたらもう少し盛り上がるかもしれないなーなんてことを思いながら見送りの方向で。

結局 Apache module タイプのツールはなんかちょっと不安が拭えないので今回はスルーで。

あと参考までに

Typepad Mobile

正式名称は結局 TypeCast でしたっけ。イマイチよく分かっていない。

これは HTML を変換するタイプではなく Atom から変換するタイプ、のはず。Atom の出力に対応しているアプリからなら簡単に使えるかもしれない。

公開時にニュースになって以降はそんなに話題になってないっぽく、移転に次ぐ移転でどこに行ったかよく分からなかったけど今は github に落ち着いてるみたい。たぶん。

今回は既存のサイトの絵文字対応で Atom は使えなかったので見送った。

PHP ライブラリタイプ

PHP では差し当たって絵文字のライブラリだけ調べた。

予想通りたくさん見つかった。でも現役でメンテされてそうなものは少ない。そして結論から言うと今回自分は何も採用はしなかった。そう、つまり自作。その理由は以下の通り。

  • mb_convert_encoding をすでに使っているコードがある
  • mb_output_handler をすでに使っているサイトがある

最近は output_handler による自動エンコーディング変換は行わないのがセオリーになっている。はず。そのためもあってか最近の絵文字ライブラリは自動変換が走ると絵文字部分は壊れてしまうものが多いみたい。

HTML_Emoji

速いらしい。

れぶろぐ - [PHP] 絵文字変換ライブラリの処理速度の比較

確かに速い。でも上に書いたように自分の要求とは合わなかった。

また、名前の通り変換ライブラリであり、例えば絵文字入りの HTML 作成を支援してくれるわけではない。UTF-8 でバイナリを直接埋め込んでいかなくちゃいけないとなると、制作現場的には厳しい。あくまで携帯から絵文字を投稿できてそれのハンドリングがちゃんとできるよっていう話のように見える。

emj

こちらは作った方がデザイン業務も行っているということで、さすがに制作現場で使いやすそうな機能を持っている。

絵文字を名前で入力できるというのは実は重要で、この方式は文字コード変換に強く、分業時にトラブルになりにくい。例えばなにがしかのテンプレートシステムと併せて使いたいとなったとき、テンプレート周りでエンコーディングの変換に気を使う必要がない。HTML_Emoji は確かに速いけれど、エンコーディング変換時には独自のメソッドの利用を要求するので「新規開発ですべて UTF-8 に統一できている」などの条件が整っていないと安心して利用することは少し難しいのだ。

そんないいことずくめそうな emj だけど、

  • ライセンスが不明
  • グローバル汚染しまくりで気持ちよくない

という辺りがネック。

Perl 使ってりゃこの辺は日本にはかなり強力なコミュニティがあるから楽できそうなんだけどね。

REXML で SAX風に id と class を抜き出してみた

こんな風に使います。

ruby class_id_picker.rb FILENAME

当然、HTML は処理できなくて、XHTML でないとダメです。

使い道は、とりあえず付けてある名前を推敲するのに使えるかなーくらい。あとは id が unique かどうかとか? 普通はこんなの要らない気がする。

attrs をチェックする際にわざわざ

//i

で引っ掛けているのは REXML でのパース時に大文字や小文字への正規化は行われないためです。

#! /usr/bin/env ruby

require 'rexml/document'
require 'rexml/streamlistener'

class ClassIdPicker
  def initialize
    @ids     = []
    @classes = []
  end
  attr_reader( :ids, :classes )

  def self.parse( io )
    obj = self.new
    REXML::Document.parse_stream( io, Listener.new( obj.ids, obj.classes ) )
    return obj
  end

  def attrs
    return instance_variables.map { |e|
      e.sub( /\A@/, '' )
    }
  end

  def browse
    puts "=== Classes ==="
    puts @classes.sort.uniq.join( "\n" )
    puts "=== Ids ==="
    puts @ids.sort.uniq.join( "\n" )
  end

  class Listener
    include REXML::StreamListener

    def initialize( ids, classes )
      @ids     = ids
      @classes = classes
    end
    attr_reader( :ids, :classes )

    def tag_start( name, attrs )
      attrs.each_pair { |name, val|
        case name
        when /\Aid\z/i
          @ids.push( val )
        when /\Aclass\z/i
          @classes.push( val )
        end
      }
    end

  end
end

if ( __FILE__ == $0 )
  app = ClassIdPicker.parse( ARGF.file )

  # 数を数えながら表示してみる
  app.attrs.each { |attr|
    p attr
    attr_list = app.send( attr ).dup
    attr_list.sort.uniq.each { |name|
      puts "#{name}\t#{attr_list.grep( name ).size}"
    }
  }
end

参考

Debian etch の Trac 0.10.3 に Web Admin Plugin

WebAdmin - The Trac Project - Trac

インストールは

TracPlugins - The Trac Project - Trac

の通りに

sudo easy_install http://svn.edgewall.com/repos/trac/sandbox/webadmin

ってやったらあっけなく済んだ。インストール先は

/usr/share/trac/plugins/

ではなく

/usr/lib/python2.4/site-packages

の方だったけど、trac.ini の方で enabled にしたら普通に認識してくれたのでよしとしよう。

あとは user をコマンドラインから

trac-admin PROJECT permission add USER TRAC_ADMIN

してやると、Web の方でいちばん右端に Admin タブが現れるので、これ以降は Web 上で管理できるようになる。user とか group 作った方がいいんだろうけど、今のところそんなに複雑な管理してないから、ここら辺はまだ放置でいいかな。外に公開もしてないし。

※ trac 0.11 ではこれは core package に入るらしいのでますます楽になるのね。

パーツショップのショッピングサイトってひどいんだなぁ

最近 Pentium M で新しいサーバを組もうと思ってパーツをあれこれ注文していた1んだけど、そこで気づいたことがある。全部かどうかは知らないが、PCショップのショッピングサイトの作りがひどすぎるということである。高木先生にたれ込んだらきっと重油吹くサイトのオンパレードだ。個人情報を入力して注文を完了させる画面において、

  • SSL 使ってない
    • あるんです!
  • オレオレ証明書
    • 少しはやる気があったんだなぁ
  • 決済処理丸投げで別ドメインの証明書2
    • しかもオレオレ
    • しかもフレーム分けてる

なんてのがザラにある。もちろん安めの店を狙っていたからなのかもしれないけど、そういうところはおまけに電話で注文を受け付けてくれなかったりする。電話掛けてもサイトから注文をお願いしますと言われる。

まぁ別にその店に個人情報が渡ったとか、パーツを買った履歴が漏れるかもしれないとか、spam が増えるかもしれないといった程度のことにこっちはそんなにビクビクしちゃいない。買い物はすべて代引きにしてるのでクレジットの情報はやりとりしてないしね。

にしてもだ。今なお Web 上で正しくセキュアな通信を行うなんてことに、中小零細のショップが気を回せるところにはきてかもしれないけれども、PCショップの客層にはそういうの詳しい人結構いるんでないかい? そういうところ気にならないのかなぁ。ショップ比較する人たちはセキュリティには興味ないのかな? もしかしてプライバシーポリシーとか特定商取引の文言があればいいの?

文句は言っているが、なぜかほしいものが扱ってる店のかなり限られたものばかりになってしまい、セキュアでないことは分かったうえで買っちまった。「こういう店では買わない宣言」できればかっこよかったかもしれないんだけどねぇ。

  1. 当然のように自分のほしいものは近場のリアル店舗にはない。自作好きではないのでパッケージの商品があればそれでもよかったんだけど、Pentium M のミニタワーで見た目もそれなりで安いものなんて全然ないので、仕方なしに作ってみることにした。まぁこういうことやっておかないと新しい規格とかさっぱり分からなくなるんで、たまにはいいかな。 

  2. 決済処理を外注することと証明書が正しくないことは別問題なんだけど、一緒くたに丸投げしてしまっているとか、外注先のレベルの低さがモロバレ。 

予想通りメールの乗り換えは恐ろしくつらい作業だ。

コンバートにも時間が掛かったが、いちいち振り分けのルールを作っていく過程がたまらなくつらい。UI なんか要らないから全部エディタでルールを書かせてくれないかと真剣に考えてしまう。トラックパッドはやはり細かい作業には向いてないって。

Datula → Thunderbird

  • Datula で mbox 形式で吐き出す
  • 拡張子を .mbx にしておく
  • Thunderbird 側で Eudora のメールをインポート
    • さっきの .mbx のファイルが置いてあるフォルダを指定すれば ok
    • ローカルフォルダ内にインポートされたメールがセットされる

Eudora ってなんだ、っていうのが正直なところ。今回のバージョンは Firefox もそうだけど、一般ユーザーをかなり意識した作りになってきているところは確かに評価できる。でもさ、mbox 形式って表記くらいは入れようよ。仮にも Thunderbird ですよ、ああた。どれだけ作り手が一般ユーザーを意識してもさ、まだマニア向けだっつの。

雑感

今回はメールボックス内に飼っていたワームが AVG に引っかかって作業が中断してしまったので、ついでに高速化のために AVG を切って作業を行った。

Thunderbird の動作は 0.6 よりは 0.7 の方が速い感じ。大量のメールデータを一気に扱う場合は Datula に比べて明らかに遅いが、まぁそんな機会はめったにあるわけでなし。それよりメール作成時に外部エディタが使えないのが痛い。細かいテキストを作るときにはやはりエディタの力がほしい。そういや昔 EdMax と Datula を比較した際にも

  • 設定が楽であること
  • 外部エディタで編集できること

で Datula に軍配を上げたような気がする。

Thunderbird の動作はまだまだこなれていない感じがする。

  • フォルダツリーでフォルダをダブルクリックすると新しいウィンドウが立ち上がる。

これはたぶんメッセージ一覧でダブルクリックしたらメッセージウィンドウが立ち上がる動作がそのまま転用されているんだろうけど、明らかに変だ。

  • メッセージを移動する際に移動中のカウントが出たり出なかったりする。

いつまで待てばいいのかよく分からなくて気持ち悪い。あんまり遅いので殺して再起動したら移動は終わってたりする。

こうして別な作業をしながらでないと続けられない。

About

例によって個人のなんちゃらです