| @技術/プログラミング

レンタルサーバーみたいな共有サーバーとか sudo 権限のないサーバーで動かしてるRailsアプリケーションを再起動したくなることがある。でもApacheをリスタートする権限がない。じゃあどうするかとググっていたらこういう記事にたどり着いた。

To restart your rails app do a "ps x" to get the pid of your dispatch.fcgi process(let's say it's 1234) then do a "kill 1234". This will kill the running process and a new one will be automatically spawned and you should now see your changes. How do I restart rails app? - DreamHost Forum

要するに ps x でRailsアプリケーションのプロセスIDを調べ、 kill #pid しちゃうというわけ。 kill できんのかなと半信半疑だったけどちゃんとできた。

他のレンタルサーバーには当てはまらないかもしれないけどメモっときます。

| @技術/プログラミング

ちょっとCakePHPで作ってるサイトでRSSフィードを配信したいと思ったのでやってみたんだけど、思いの外面倒くさくてびっくりした。『RailsによるアジャイルWebアプリケーション開発』を読みながらRails 2.3.5でRSSフィード作るときは結構簡単だった気がするので、正直これはないわと思った。

『Railsによる〜』で作ってるデモプロジェクトのdpeotのコードを見てみると、RSSを配信するときはControllerに以下のように記述し、

respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @products }
end

config/routes.rb

map.connect ':controller/:action/:id.:format'

と書いたあと、RSS用のViewを用意してやるだけだ。ものすごくシンプルで簡単だった。

CakePHPで同じことをやるためには以下の手順が必要。

ちょっと面倒くさすぎてやる気にならなかった。どうせいま僕が作ってるサイトなんてRSSリーダー使うような人が見るサイトじゃないし、フィード配信機能の実装はそんなにプライオリティ高くないので他にやることがなくてどうしようもなく暇なときにでもやろう。

Railsは最初のとっかかりのハードルは高いけど、使い方を覚えていったらやっぱりCakePHPとかよりも全然簡単かつ高速に開発できる気がする。レールに乗ってる感強い。このMephistoの設置もすごく楽だった。ただTerminalを使い慣れた人や、サーバーにSSHでアクセスできる環境じゃないとRailsアプリケーションを使うのは難しい。CakePHPは反面、全部FTPでアップロードすれば良いのでサーバーに標準的な構成でPHPがインストールされてりゃ環境構築でつまずくことはない。どっちをとるかって話ですよね。

僕はファッションの観点からRailsを選びたい。

| @技術/プログラミング

『Railsによるアジャイル〜』とかのコードはViewの部分がスゲーシンプルで、ロジックがほとんど書いてない。これに慣れると、CakePHPに戻って自分が作ってるウェブアプリを見たときに、Viewに結構ロジックが書いてあって愕然とする。例えばフラグをたてて条件にマッチすれば日付を表示し、マッチしなければ表示しないとかしたいとするじゃないですか。Controllerでそういう設定できなくないけど長くなる。Viewの中に書いてしまったら数行で済むし。

だから僕の作ってるCakePHPアプリはMVCとか名ばかりでViewのコード超きたない。入れ子になったif文がたくさんあるし、正規表現で日付の書式変更とかまでやってる。さすがに関数とかは定義してないですけどね。

そもそもCake FoundationのCakeBookも結構Viewにロジックが書いてあったりする。というかかなりハードに書いてある。CakePHPってViewとロジックを分離させるのが難しいのかな。

加えて、Controllerも結構ひどいことになってる。本当はModelに書くべきことを結構Controllerに書いている気がしないではない。サイト検索のためのメソッドとか200行近くあるし、joinとかしまくり。

MVCでロジックとヴューを分離することでデザイナーがViewを触れるようになって分業が進むかもとか思ってたけど、到底そんな状況にないですね。

| @技術/プログラミング

Gitでbranchの効率的な使い方みたいのがよくわからない。

  • 実験的な機能をつけたい

  • ブランチを分ける(例えば開発用に alternate というブランチを作る)

  • 開発する

  • 開発完了後、 master にマージ

みたいな感じかなと思ってた。

しかし実際に運用してみると、実験的な機能の実装の他に、日常的にmasterでコードの改良みたいな作業があり、alternateで開発が完了した後にmasterにマージしたら多分コンフリクト起こりまくりになるような気がしてきた。

それで日常メンテみたいな作業はmasterブランチで行い、それをalternateにマージするという手順をとってる。正しい開発方法かどうかはわからないけど、一応alternateブランチもmasterの最新の変更を追跡できる。んでalternateではしこしこ開発を続けて、開発完了時にmasterにマージしても多分派手なコンフリクトは起こらないんじゃないかと思ってますがどうなんでしょう。

| @技術/プログラミング

こういうコード書いてます。

function getAttrName(attrObj) {
    var attrName = attrObj.firstChild.data;
//  items = document.getElementsByClassName('item');
    var items = $('li.item');
    $(items).fadeOut('slow');
    for (var i = 0; i < items.length; i++) {
    //  var keywordList = items[i].getElementsByClassName('keyword-list');
        var keywordList = $('.keyword-list', items[i]);
        for (var j = 0; j < keywordList.length; j++) {
            //var keywords = keywordList[j].getElementsByTagName('li');
            var keywords = $('li', keywordList[j]);
            for (var k = 0; k < keywords.length; k++) {
                if (attrName == keywords[k].textContent) {
                    $(items[i]).fadeIn('slow');
                }
            }
        }
    }
    getCurAttr(attrName);
}
function getCurAttr(attrName) {
    var curAttr = $("#keySelector li a");
    for (var l = 0; l < curAttr.length; l++) {
        if ($(curAttr[l]).text() == attrName) {
            $(curAttr[l].parentNode).addClass('current-keyword');
        } else {
            $(curAttr[l].parentNode).removeClass('current-keyword');
        }
    }
}

やりたいことは以下のような感じ。

  1. onclickで attrObjgetAttrName に渡される
  2. クリックされた文字列を attrName に格納
  3. すべての item をjQueryを使って非表示
  4. item の中の ul.keyword-list li 内のテキストに一致したらjQueryで表示

Firefox/Safari/Operaでは問題なく動く。しかしIEが全滅。最初は getElementByClassName とか使ってるからかと思ってたけど、その辺のやつをコメントアウトしてjQueryセレクタを使ってオブジェクトを取得するようにしてもダメ。なんかループの処理とかが怪しいんじゃないかと思ってる。ループ処理もjQueryに書き換えようかな。

ブラウザ間の挙動の違いを吸収してくれるライブラリはまじですごいしありがたいのですが、結局IEちゃんでは動かせない。歯がゆいな。

サーバーサイドで実装する方法もないではないけど、

  1. いじる部分が広範囲になりめんどい(新たなバグが発生するかも)
  2. 大した機能じゃないのに大手術したくない
  3. ずっとPHPばっかり触ってるのはつまらん

などという理由により期限ぎりぎりまでJavaScriptで粘ってみたいです。

追記

"Twitterでcxxさんに教えてもらった":http://twitter.com/cxx/status/13545498622 んだけど、IEにはtextContetはないそうです。恥ずかしい。

そういうわけで

var keywords = $('li', keywordList[j]);

var keywords = $('li a', keywordList[j]);

とし、

if (attrName == keywords[k].textContent)

if (attrName == keywords[k].firstChild.data)

にしてみたところ、ばっちりIEで動くようになった。

cxxさんありがとうございます。今度焼き肉デートしましょう。

| @技術/プログラミング

ポータルシットがクソ重くて、なんか対策ないかなーとか仕事をさぼりながらときどき調べてた。

おおよその原因は掴んでいた。それはアクセス解析プラグイン。MySQLのデータ容量がでかくなるとページの表示が遅くなる。アクセス解析プラグインを無効にした状態でページの表示速度はだいたい0.05秒くらいなんだけど、アクセス解析プラグインを有効にすると表示速度は1秒台とかまで悪化する。アクセス解析に使うテーブル( p_page_analyze )をDROPするとまた速さが回復するので時々空にしていた。

しかしよくよくアクセス解析プラグインのコードを覗いてみると、ヴュー部分で使っていないSQLクエリが発行されており、このせいでクエリの回数が必要な回数の何倍にもなっていた。ポータルシットのアクセスなんて大したことないんだから、DBのサイズがちょっとでかくなっただけでこんなに遅くなるはずがないのだ。

そういうわけで不必要なクエリのトリガーになるコードをコメントアウトしてみた。すると1秒台だった表示速度は0.2秒から0.5秒程度に収まるようになった。しかしそれでもなんか遅く感じる。

それでキャッシュを効かせることにしてみた。使ったのはPecl APC。DreamHostはなんでもやらせてくれるのでほんと助かる。

Pecl APC - DreamHost を見ながらシェルスクリプトをコピペして走らせ、php.iniにAPCの設定を書き加えて終了。僕はPHPのバージョンを5.3.1に上げているのでコピペしたシェルスクリプトのまんまではきちんと入らなかった。最新版のAPC(APC-3.1.3p1)にバージョン情報を書き換えてインストールしたところうまくいった。またDreamHost Wikiではキャッシュファイルのパスが /home/username/tmp/apc.*XXXXXX* だったり /home/username/tmp/apc.*XXXXX* だったりばらついてるけど、Xの数は6個じゃないと500エラーが出るのでご注意を。

キャッシュを効かせて見た結果、フッターのPage Generationはあまり変化がないが、体感速度は十分に速くなった。

| @技術/プログラミング

CakePHP 1.3のStableがリリース された。 JavascriptヘルパーとかAjaxヘルパーが非推奨になってる 。かわりにHtmlヘルパーのjsメソッドを使うらしい。 $html->js('') みたいな感じかな。で、Ajax系の処理はjQueryがデフォルトのライブラリになったらしい。Rails 3.0もprotorype.jsに別れを告げたらしいし、自分がJavaScriptのライブラリで遊び始めた頃はjQueryが全盛だったのでいまからprototype.jsの使い方勉強するのかったるかったし、jQuery簡単だしこの進化は大歓迎です。

JavascriptヘルパーとAjaxヘルパーが非推奨になった件については、わざわざ別のヘルパーにせんでもいいよなー、という印象は確かに持ってた。Htmlをいじるメソッドは一つのヘルパークラスにまとめてしまった方がすっきりする。1.2.xのときはAjaxヘルパーが使いづらすぎて結局jQueryでAjaxすることもあったし、あまり存在意義を見いだせなかったので良かったんじゃないでしょうか。

でも既存のプロジェクトの1.3への移行はめんどくさそうなのでたぶんやんない気がする。新しくCakePHPでなんか作るときは使ってみようと思います。