Stellaqua - TOMの技術日記 このページをアンテナに追加 RSSフィード

2010年08月08日

[]Amazon EC2上のHadoopMeCabを使えるようにしてみた…い

最近すっかり"Webサービスを作ってみた"系の記事ばっかりでしたが、今回は久々にEC2上でのHadoopのお話。

以前の記事EC2上でHadoopを動かした時は、MeCabデフォルトで入っていなかったので、事前に自宅サーバ上で分かち書きしたデータを使っていました。

ただ、日本語処理するならMeCabはほぼ必須だろうし、せっかくならMeCabが使える状態でMapReduceしたいのが人情ってもんです。

という訳で、EC2上のHadoopを使って、MeCabを利用した日本語文章の単語カウントMapReduceに挑戦してみました。

基本的な方向性としては以下の通りです。

  1. EC2上でインスタンス起動。
  2. 起動したインスタンスMeCabインストール
  3. AMIとして保存。
  4. Hadoopを起動する時にこのAMIが使われるようにする。

で、実際にやってみた訳なんですが、結論から言うとうまくいきませんでした…。

AMIを保存して、そのAMIが使われるようにするところまではできたんですが、そのインスタンスログインできない状態になってしまって、実際にMeCabを利用したMapReduceを動かすところまでできていません。

という事で途中までではありますが、やってみた手順を書き残しておきたいと思います。

以下、"[local]$"がローカルのサーバ上、"[ec2]$"がEC2上でのプロンプトを表す事とします。

EC2上でHadoopを起動してログインする

まずはEC2上にインスタンスを1つ起動させてログインします。

[local]$ hadoop-ec2 launch-master hadoop-test 1
[local]$ scp -i stellaqua.id *.pem root@ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:/mnt
[local]$ hadoop-ec2 login hadoop-test

タイムゾーンを変更する

今回(というか毎度)参考にさせて頂いているid:rx7さんの記事によるとタイムゾーンの設定をしておいた方がよいとの事なので、ついでにここでタイムゾーンの変更をしておきます。

[ec2]$ cp /usr/share/zoneinfo/Japan /etc/localtime
cp: `/etc/localtime' を上書きしてもよろしいですか(yes/no)? y

MeCabインストールする

続いて本命のMeCabインストールします。

[ec2]$ yum -y update
[ec2]$ yum -y install mecab mecab-devel mecab-ipadic
[ec2]$ echo 'こんにちは' | mecab
こんにちは      感動詞,*,*,*,*,*,こんにちは,コンニチハ,コンニチワ
EOS

ちゃんとMeCabが使えるようになりましたね!

EC2root権限が与えられるので、yumで必要なものをガシガシ入れてしまうとよいですね。

AMIを作成してS3にアップロードする

AMI作成の手順については、毎度お世話になっているid:rx7さんの記事を参考にさせて頂きました。

Amazon EC2/S3を使ってみた - 3.EC2起動後〜AMI作成 - 元RX-7乗りの適当な日々

[ec2]$ cd /mnt/
[ec2]$ ec2-bundle-vol -d /mnt --privatekey pk-XXXX.pem --cert cert-XXXX.pem --user XXXX-XXXX-XXXX -p hadoop-0.17.0-i386 -r i386
[ec2]$ ec2-upload-bundle --bucket stellaqua/ec2_images/hadoop_mecab --manifest hadoop-0.17.0-i386.manifest.xml --access-key XXXX --secret-key XXXX
[ec2]$ exit
[local]$ hadoop-ec2 terminate-cluster hadoop-test
[local]$ ec2-register stellaqua/ec2_images/hadoop_mecab/hadoop-0.17.0-i386.manifest.xml
IMAGE   ami-XXXX
[local]$ vi hadoop-ec2-env.sh
→"S3_BUCKET=hadoop-ec2-images"となっているところを、上記で指定したバケットに変える

ポイントは、manifestファイルをHadoopのバージョンとアーキテクチャの名前を付けて保存する事と、設定ファイルでAMIを保存したバケットを設定しておく事ですね。

これで、hadoop-ec2コマンドでHadoopを起動する時に、登録したAMIが使われるようになるはずです。

早速、クラスタを起動してログインしてみます。

[local]$ hadoop-ec2 launch-cluster hadoop-test 1
[local]$ hadoop-ec2 login hadoop-test

これでログインできるはずなんですが、なぜかログインしに行ったままウンともスンとも言わない状態になってしまいます。

"Permission denied"とも言われないし、netstatで見るとESTABLISHEDにはなっているので、接続自体はできているとは思うのですが…。その後も色々試してはみたんですが、現時点でお手上げ状態になっています…。

また折を見て試してみて、うまくいったら記事にしようかなと思います。

2009年03月30日

[][][]四角い地球の歩き方 その1「地箱を作ろう」

前回の記事の内容がめでたくシリーズモノに昇格いたしました。パチパチ。

きっかけは1年越しに唐突に…

前回、唐突に3Dの話をし始めたのには理由がありまして…もう1年以上も前なんですが、2chまとめサイトで、"もしも地球が正方形だったら"っていうタイトル*1のスレを見たのが、そもそものきっかけでした。

F速VIP(・ω・)y-? もしも地球が正方形だったら

これが非常に想像力を掻き立てられて、自分なりに「どうなるんだろうか?」と色々と想像を膨らませておりました。*2

この時は「面白いなぁ。」だけで終わったんですが、最近急に「これって、Flashとかで3D処理すれば、実際に立方体地球の上を歩くシミュレーションが作れるんじゃね?」となぜだか急に思ってしまい、Flashの3D処理について唐突に調べ始めた…というのが事の顛末だったりします。

このシリーズの趣旨

Flashの3D処理の勉強も兼ねて、立方体地球の上を自由に歩き回れるシミュレーションを作る事を目標に、備忘録として記事を書きながら、少しずつ実装を進めていきたいと思います。

教科書代わりのサイト

前回の記事のリンクにも入れたんですが、rectさんという方のnote.xというブログが激しく参考になるので、こちらを教科書代わりに利用させて頂こうと思っています。

note.xさんの記事を一通りざっと読ませて頂いて、PaperVision3D 2.0を使った方が良さそう、という事と、あとAway3DっていうPaperVision3Dからの派生プロダクトも良さげ、という事が分かりました。

今回のシリーズ記事では、基本的にはPaperVision3D 2.0を使って、場合によってAway3Dを使ってみたり、あとは物理エンジンにも手を出せたらいいなと思っています。

今回の目標

という訳で、ここからが本題。今回は、立方体地球を表示させるところまでをやってみます。

ちなみに、"立方体地球"といちいち書くのも面倒なので、以降は"地箱"と書いていこうと思います。

世界地図のテクスチャを用意する

地箱を作るには、基本的には世界地図の絵を立方体に貼り付ければいいだけなので、まずは世界地図のテクスチャを探します。

幸い、note.xさんでフリーで使える地球テクスチャについて言及されている記事があって、それによると、以下のサイトでダウンロードできるとの事。

Planet Earth Texture Maps

「サイズが1KBytesのものはフリー」と書いてあるので、ありがたく使わせて頂く事にします。

テクスチャ立方体に貼り付ける

テクスチャが手に入ったので、続いて、note.xさんの以下の記事を参考に、テクスチャ立方体にペタペタと貼り付けていきます。

no title

ただ、立方体の展開図は当然長方形ではない訳で、そのままじゃうまく貼れないので、以下のような展開図で貼り付ける事にしました。

f:id:stellaqua:20090330201343j:image

当然、上面と下面はおかしな事になるけど、本筋ではないので今回はこれで妥協…。

図に示した前後左右上下は、camera.zの値を負に設定した時に手前に見えている面を前とした時の方向です。三角形ごとに付いている番号は、cube.geometry.faces[no]として面を取得した時に、どの番号がどの三角形に対応するかを記したものです。

ちなみに、note.xさんの記事で"Planeの頂点とUVとの関連づけ"の説明図通りにUVを設定すると向きがずれてしまったんですが、以下のような対応にしてやったらうまくいきました。

f:id:stellaqua:20090330201437p:image

Planeでやると確かにnote.xさんの記事の通りになるので、どうやらPlaneCubeで生成される三角形面の頂点の定義が異なるようですな。

今回の成果物

という事で、ひとまず地箱のベースの完成です。

直リンクhttp://www.stellaqua.com/swf/EarthCube1.swf

せっかくなので、地軸を見えるようにして、地軸が傾いた状態で自転させてみました。

ソースコードはこの記事の最後に載せておきたいと思います。

次回は?

最終的には一人称視点で自由に歩き回れるようにしたいんですが、その前にまずは地箱の面上を歩き回った時に、面上の自分の座標から三次元座標への変換ができないといけないので、次回はその辺りに挑戦してみたいと思います。

それにしても、3Dの世界は、一歩足を踏み入れると泥沼の楽しさでヤバ過ぎる…。(笑)

ソースコード

package
{
    import flash.display.*;
    import flash.events.*;

    import org.papervision3d.view.*;
    import org.papervision3d.events.*;
    import org.papervision3d.core.math.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.*;

    [SWF(backgroundColor=0x000000)]

    public class EarthCube1 extends BasicView
    {
        private var rootNode   : DisplayObject3D;
        private var objCube    : Cube
        private var ang        : Number = 0;

        [Embed(source='earthmap1k.jpg')] public var texBitmap:Class;

        public function EarthCube1()
        {
            stage.frameRate = 30;
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.MEDIUM;

            //viewportの定義とカメラタイプ定義
            super (0,0,true,true,"Target");
            init3D();
        }

        public function init3D():void
        {
            rootNode = new DisplayObject3D();
            scene.addChild(rootNode);

            //カメラ設定
            camera.z = -1200;
            camera.y = 500;
            camera.fov = 30;

            //マテリアル設定
            var material:BitmapMaterial = new BitmapMaterial(new texBitmap().bitmapData, true);
            material.interactive = true;
            material.precise = true;
            var materials:MaterialsList = new MaterialsList({all : material});

            //Cubeオブジェクト生成
            objCube = new Cube(materials, 250, 250, 250, 1, 1, 1);
            rootNode.addChild(objCube);

            //テクスチャ変更(前面)
            objCube.geometry.faces[ 2].uv0 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[ 2].uv1 = new NumberUV(1.00, 0.25);
            objCube.geometry.faces[ 2].uv2 = new NumberUV(0.75, 0.75);
            objCube.geometry.faces[ 3].uv0 = new NumberUV(1.00, 0.25);
            objCube.geometry.faces[ 3].uv1 = new NumberUV(1.00, 0.75);
            objCube.geometry.faces[ 3].uv2 = new NumberUV(0.75, 0.75);

            //テクスチャ変更(後面)
            objCube.geometry.faces[ 0].uv0 = new NumberUV(0.25, 0.25);
            objCube.geometry.faces[ 0].uv1 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[ 0].uv2 = new NumberUV(0.25, 0.75);
            objCube.geometry.faces[ 1].uv0 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[ 1].uv1 = new NumberUV(0.50, 0.75);
            objCube.geometry.faces[ 1].uv2 = new NumberUV(0.25, 0.75);

            //テクスチャ変更(左面)
            objCube.geometry.faces[ 4].uv0 = new NumberUV(0.00, 0.25);
            objCube.geometry.faces[ 4].uv1 = new NumberUV(0.25, 0.25);
            objCube.geometry.faces[ 4].uv2 = new NumberUV(0.00, 0.75);
            objCube.geometry.faces[ 5].uv0 = new NumberUV(0.25, 0.25);
            objCube.geometry.faces[ 5].uv1 = new NumberUV(0.25, 0.75);
            objCube.geometry.faces[ 5].uv2 = new NumberUV(0.00, 0.75);

            //テクスチャ変更(右面)
            objCube.geometry.faces[ 6].uv0 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[ 6].uv1 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[ 6].uv2 = new NumberUV(0.50, 0.75);
            objCube.geometry.faces[ 7].uv0 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[ 7].uv1 = new NumberUV(0.75, 0.75);
            objCube.geometry.faces[ 7].uv2 = new NumberUV(0.50, 0.75);

            //テクスチャ変更(上面)
            objCube.geometry.faces[ 8].uv0 = new NumberUV(0.75, 0.75);
            objCube.geometry.faces[ 8].uv1 = new NumberUV(1.00, 0.75);
            objCube.geometry.faces[ 8].uv2 = new NumberUV(0.75, 1.00);
            objCube.geometry.faces[ 9].uv0 = new NumberUV(0.25, 1.00);
            objCube.geometry.faces[ 9].uv1 = new NumberUV(0.25, 0.75);
            objCube.geometry.faces[ 9].uv2 = new NumberUV(0.50, 0.75);

            //テクスチャ変更(下面)
            objCube.geometry.faces[10].uv0 = new NumberUV(1.00, 0.25);
            objCube.geometry.faces[10].uv1 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[10].uv2 = new NumberUV(1.00, 0.00);
            objCube.geometry.faces[11].uv0 = new NumberUV(0.50, 0.00);
            objCube.geometry.faces[11].uv1 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[11].uv2 = new NumberUV(0.25, 0.25);

            //地軸オブジェクト生成
            var objAxis:DisplayObject3D = drawAxis(0xff3333);
            rootNode.addChild(objAxis);

            //地軸を傾ける
            rootNode.rotationZ = -23.4;

            //レンダリング開始
            startRendering();
        }

        override protected function onRenderTick(event:Event=null):void
        {
            ang = ( ang - 1 ) % 360;
            objCube.rotationY = ang;

            super.onRenderTick(event);
        }

        private function drawAxis(color:uint):DisplayObject3D {
            //色設定
            var colorMaterial:ColorMaterial = new ColorMaterial(color, 1);
            colorMaterial.doubleSided = true;
            
            //円柱を作る
            var axis:DisplayObject3D = new Cylinder(colorMaterial, 2, 400);
            
            //円柱の先に球を作る
            var sphere1:DisplayObject3D = new Sphere(colorMaterial, 10);
            var sphere2:DisplayObject3D = new Sphere(colorMaterial, 10);
            sphere1.y = 200;
            sphere2.y = -200;
            
            var node:DisplayObject3D = new DisplayObject3D();
            node.addChild(axis);
            node.addChild(sphere1);
            node.addChild(sphere2);
            
            return node;
        }
    }
}

*1:スレを立てた人は立方体の事を言いたかったようなので、そもそもタイトルが変ではありますが…。

*2:こういう科学系の思考実験は大好きなんです。

2009年03月29日

[][]PaperVision3Dを使ったFlashの3D処理のお勉強

今日は気まぐれで、Flashでの3D処理についてのお話。

ちょっと調べてみると、どうやらPaperVision3DというのがFlashで3D処理を行うライブラリとして有名らしいので、PaperVision3Dの基本的な使い方を調べてみました。

ライブラリの入手

ライブラリのソースはSVNリポジトリで公開されているので、そこから最新版を入手します。

http://papervision3d.googlecode.com/svn/trunk/

自分の場合は、TortoiseSVNでPC上にエクスポートしてきました。

最新版は2.0αというバージョンなんですが、1.xと2.xで実装がだいぶ変わっているらしく、ネット上で自分が調べた範囲でのサンプルコードが1.x用のものが多かったので、今回は1.7というバージョンを使う事にしました。

ただ、2.0だとシェーディングができるようになったり等、色々と機能追加があるようなので、2.0の使い方を勉強した方が後々の為には良いのかもしれません。

サンプルを作ってみる

基本的な使い方については、最後に参考にしたサイトのリンクを並べておいたので、そちらを参照。

実際のコードの流れとしては、次のような感じになります。

何か面白いサンプルネタが無いかなと考えていたんですが、あまり複雑になり過ぎない範囲で面白そうなネタが思い付かず、参考にしたサイトのサンプルコードをちょっと弄る程度にしておきました。

という事で、DoCrystalで生成した当ブログの結晶画像をマテリアルにした面を回転させて並べて、結晶を立体っぽく見せるサンプルを作ってみました。

ソースコードは以下の通り。

package {
    import flash.display.*;
    import flash.events.*;
    
    import org.papervision3d.scenes.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;
    
    [SWF(backgroundColor=0xeeeeff)]
    
    public class DoCrystalFlash extends Sprite {
        private var container : Sprite;
        private var scene     : Scene3D;
        private var camera    : Camera3D;
        private var rootNode  : DisplayObject3D;
        
        private var planeSize : int = 300;      //Planeオブジェクト1辺の長さ
        private var segment   : int = 2;        //面の分割数
        
        private var valx      : Number = 0;
        private var valy      : Number = 0;
        
        public function DoCrystalFlash():void {
            stage.frameRate = 60;
            stage.quality   = "BEST";
            stage.scaleMode = "noScale";
            stage.align = StageAlign.TOP_LEFT;
            this.addEventListener(Event.ENTER_FRAME, loop3D);
            this.stage.addEventListener(Event.RESIZE, onStageResize);
            
            init3D();
        }
        
        private function init3D():void {
            //コンテナ生成
            this.container = new Sprite();
            addChild(this.container);
            this.container.x = this.stage.stageWidth  / 2;
            this.container.y = this.stage.stageHeight / 2;
            
            //シーン生成
            scene = new Scene3D( container );
            
            //カメラ設定
            camera = new Camera3D();
            camera.z = -planeSize;
            camera.focus = 300;
            camera.zoom = 1.5;
            
            //rootNode生成
            rootNode = scene.addChild( new DisplayObject3D( "rootNode" ) );
            
            //マテリアル設定
            var imageMaterial:BitmapFileMaterial = new BitmapFileMaterial( "stellaquacrystal.png" );
            imageMaterial.smooth = false;
            imageMaterial.doubleSided = true;
            //var color:uint = 0x9999ff;
            //var colorMaterial:ColorMaterial = new ColorMaterial(color, 1);
            
            var compoMaterial:CompositeMaterial = new CompositeMaterial();
            //compoMaterial.addMaterial(colorMaterial);
            compoMaterial.addMaterial(imageMaterial);
            compoMaterial.doubleSided = true;
            
            //Planeオブジェクト生成
            for ( var i:int=0; i<3; i++ ) {
                var planeObj:DisplayObject3D = new Plane( compoMaterial, planeSize, planeSize, segment, segment);
                planeObj.rotationY = i * 60;
                rootNode.addChild( planeObj );
            }
            scene.addChild( rootNode );
        }
        
        private function loop3D( event:Event ):void {
            //マウス座標でオブジェクトを回転
            valx -= this.container.mouseX / 50;
            valy -= this.container.mouseY / 50;
            rootNode.rotationY = valx;
            //rootNode.rotationX = valy;
            
            //レンダリング
            this.scene.renderCamera( camera );
        }
        
        private function onStageResize(event:Event):void {
            this.container.x = this.stage.stageWidth  / 2;
            this.container.y = this.stage.stageHeight / 2;
        }
    }
}

見ると分かりますが、参考にしたサイトのサンプルコードをかな〜りパクらせてもらっています。(^^;ゞ

コンパイルする時は以下のような感じ。

C:>mxmlc -compiler.source-path=c:\path_to_papervision3d\as3\tags\1_7\src DoCrystalFlash.as

実物はこちら。

(追記:やっぱりうまく表示できていなかったので、ガジェットコメントアウトしました。デモは下記の直リンクからどうぞ。)

マウスカーソルの位置によって回転速度と向きが変わります。

結構うねうねとスムーズに動くもんですな。ただ、角度が付いてる時のテクスチャの表示が若干おかしいような気が…。この辺りは要調査…。

(追記:テクスチャが歪むのはsegmentを1にしてたからでした。2に設定してみたらキレイに表示されるようになりました。)

ちなみに、id:nitoyonさんのFlash埋め込みガジェットを使わせて頂きましたが、ちゃんと動いてるかな?

うまく見れない時用の直リンクhttp://www.stellaqua.com/docrystalflash/DoCrystalFlash.swf

それにしても、思っていた以上に簡単で直感的に3D処理ができるもんですな。こういう技術は遊び甲斐があって素敵ですね。

参考にさせて頂いたサイトのリンク

2009年03月26日

[][]Redmineをインストールしてみた

我らが中継職人、id:i_ogiさんの動画公開ブログ(笑)で、先日の第41回PHP勉強会の動画を見させて頂きました。

第41回PHP勉強会@関東のムービー - おぎろぐはてな

id:yandodさんの発表のRedmineがちょっと気になって、試しにインストールだけしてみました。以下、手順の備忘録…。

RubyとRailsはインストール済みなので、その辺りの導入手順は省略。バージョンはそれぞれ、Rubyが1.8.4、Railsが2.1.2です。

手順は、Redmine.JPのインストール手順ページを参考にしました。まずはRedmineのインストールから。

$ cd ~/htdocs
$ svn checkout http://redmine.rubyforge.org/svn/branches/0.8-stable redmine

続いて、database.ymlの設定をして、DBのMigrateと初期データ投入を行います。

$ cd redmine
$ cp -i config/database.yml.example config/database.yml
$ vi config/database.yml
 :
production:
  adapter: postgresql
  database: redmine_production
  host: localhost
  username: user
  password: pass
  encoding: utf8
 :
$ createdb -U user -E utf8 redmine_production
$ rake db:migrate RAILS_ENV=production
$ rake load_default_data RAILS_ENV=production
Select language: bg, ca, cs, da, de, en, es, fi, fr, he, hu, it, ja, ko, lt, nl, no, pl, pt, pt-br, ro, ru, sk, sr, sv, th, tr, uk, vn, zh, zh-tw [en] ja

次に、メール周りの設定。

$ cp -i config/email.yml.example config/email.yml
$ vi config/email.yml
 :
production:
  delivery_method: :smtp
  smtp_settings:
    address: localhost
    port: 25
    domain: example.com
 :

後はscript/serverで起動すればいいんですが、手順に、”Apache上でRuby on Railsアプリケーションを動かす/Passenger(mod_rails for Apache)の利用”というのがあったので、そっちを試してみました。

$ gem install passenger
$ passenger-install-apache2-module
$ vi /etc/apache2/httpd.conf
 :
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.1.2/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.1.2
PassengerRuby /usr/bin/ruby1.8
 :
$ cp -i dispatch.cgi.example dispatch.cgi
$ vi config/environment.rb
 :
ENV['RAILS_ENV'] ||= 'production'
 :

本当はバーチャルホストを切って、DocumentRootを設定するべきですが、ちょっと試してみるだけなので、今回はDocumentRoot直下に直接redmineディレクトリを突っ込んでいます。

ここまで設定したところでブラウザからアクセスしてみたら、無事にHome画面が表示されたので、とりあえず導入はうまくいったようです。

ちなみに、Passengerを使わずに、Mongrelで動かしてApache経由でアクセスする場合には、以下のようにします。

$ /usr/bin/ruby1.8 /usr/bin/mongrel_rails start -p 3001 -e production -P ./tmp/pids/mongrel.pid -d --prefix /redmine
$ cd ~/htdocs/redmine
$ vi .htaccess
RewriteEngine On
RewriteRule ^(.*)$ http://localhost:3001/redmine/$1 [P]

"script/server"だとprefixが指定できないので、Mongrelを直接実行しています。こうしてやると、ディレクトリ毎に違うポート番号でRailsを動かす事ができるので、なかなかに便利です。

少しだけ触ってみた感想

Passenger上で動く設定でちょっと触ってみたところ、レスポンスが非常に重たくてまともに使えそうになかったので、mongrel上で動かすようにして色々と触ってみました。*1

ざっと設定周りを見てみただけでちゃんと使ってはいないですが、かなり柔軟に色々設定できて、なかなか使い勝手は良さそうですね。

とりあえず個人的なBTSとして使ってみて、良さそうだったら本格的にバグ管理用に使ってみようかなと思います。

あとがき

ちょこちょこと手順は省いている部分もあるのであっさり導入できたように見えますが、実際にはところどころ躓きながらなので、導入完了まで結構な時間が掛かってしまいました。

id:yandodさんが発表の中で、「インストールは気合」とおっしゃってましたが、正にその通りだと思いました…。

バージョンがらみの問題で一旦ruby自体の入れ直しなんてしてしまったせいもあるんですが、「面白そうだからちょっと試してみよ。」と言うにはちょっと手間が掛かり過ぎてしまった感じがします。(-_-;)

最初にRailsを入れた時にやたらと苦労した事もあって、RailsとRuby周りに対してはどうもあまりいい印象が無いんですよね…。まぁ、素人がおいそれと入ってはいけない聖域なんでしょうね、きっと…。

*1:Rails上のログだと処理にほとんど時間が掛かっていなかったので、Passengerが重たいんだと思いますが、何か設定が良くないのか、それともPassengerっていうのはこういうもんなんでしょうか…?