2008年12月アーカイブ

仕事納めで仕事始め

今日で会社は仕事納め。

ただ、私的にはこの休みを利用して、知り合いから請け負った仕事を進めないといけないので、仕事始め。というか、しばらくサボってたので再開。

というわけで(?)、1年を振り返っておこうかと思います。

今年書いたブログ記事はこれを含めて 142 件だった様です。大分ペースが落ちている気がします。まあ、数だけ考えれば 3 日に1件なので、書いている方でしょうね、きっと。いつ頃からか、新しいウェブのサービス類を追いかける事を止めてしまい、ネタ自体がなくなってきています。書きはじめの頃は Flash やってみたりしてたわけですけど、もう、すっかり触ってません。GUI をどうこうする事を諦めているので。

それで、GUI を諦めた上に基礎力がさっぱり無いままではいかんと、低めのレイヤのところを勉強しようとあれこれしたのが、今年です。低めのレイヤと言いつつも、上澄み部分しか学べてないですね。システムコールやらインフラ関連やらの本を色々と読んでみたりしたくらいです。ただ、今の会社に入社した頃に比べれば、大分理解できる様になってきたつもりです。

あと、大きな変化として、Ruby (Ruby on Rails)を使う様になったという事があります。会社の都合上、今年の3月から Ruby を利用したサービス開発に参加する様になりました。それ以前からうさぎ本を読んだり、デプロイツールに Capistrano を利用したりする程度の付き合いはありましたが、本格的に Ruby を利用する様になったのはこの時からです。

会社の先達に導かれるまま、10ヶ月くらい。それなりに、Ruby っぽい書き方・考え方ができる様になりつつあるかな、と思います。が、まだまだ分かってない時が目立ちますね。チームの方々には迷惑をかけ通しです。

それと、関係あるのかよく分かりませんが、Ruby を使う様になってから、よくソースを読む様になりました。Rails もそうですし、Rack や Rails Engines 、Capistrano などもそうですね。大分、Google 離れが進んで一人歩きできる様になってきた気がしてますが、気のせいかもしれません。ひどい時は、man すら読まずに即 Google で、しかも検索結果の Manpage のやつを無視して、誰かが書いた記事を当てにしてたりしましたからね。

Ruby はソースを読む気にさせるのかもしれません。Ruby 界の方々が Ruby の特徴をどのように捉えているのか、あまり把握してなかったりしますが、個人的な実感として、可読性というか表現力というか、まあその辺に長けている様な気がします。Ruby をほぼそのまま DSL にできる力は気に入っています(RSpec とか Capistrano とか Rails とか、とか)。

なんだか、振り返りというか Ruby の感想みたくなってきましたね。まあ、今年一番の出来事と言えば、「Ruby でお仕事」だったので、仕方のない事です。

後は、技術チームのハンドリング(?)的な役割も仰せつかったりしましたが、会社の人はみんな自分より優秀な人ばかりなので、ちょちょいと雑用をこなした程度ですね。まあ、中二っぷりをいかんなく発揮して大混乱を招いたりもしましたが、いい思い出です。

リーダー的役割の中で、一番の功績として誇れるものは、mac 化計画が順調だと言う事ですかね。技術者 8 人中 6 人が mac を使う様になりました。また、会社では Linux で自宅で mac を使う様になった人も含めれば、残すは後 1 人。ただ、最後の 1 人が難関です。と、言いつつ、mac は少数派でこそ mac だと考えている自分もいたりして、難しいところです。本当、人生ままならないものですね。

さて、そんなこんなの 1 年間でした。2009 年の目標等は、また年が明けてから。

今までは、(癖のある)正規表現でただ置換する事しか考えた事がなかったわけですが。
新Emacsの強力な置換機能を使いこなす - ZDNet Japan

行番号みたく、行頭に連番を挿入したい場合も、replace-regexp を使えば簡単にできました。

M-x replace-regexp
Replace regexp: ^\(\)
Replace regexp ^\(\) with: \,(1+ \#)

まじめに replace-regexp の使い方やら機能やらを調べた事がなかったので、まったく知りませんでした。ぷろぐらまぶるなんですね。

なんか、ワクワクしてきた!


連番生成を考えた場合は、replace-regexp だとあらかじめ置換対象を用意しなければならないので、最適な方法ではないかもしれません。↓では、また別の方法が紹介されてます。
Emacsで連番を挿入する方法 - ’(rubikitch wanna be (a . lisper))

1点とったときの、あの感動っぷりに激しく違和感というか、温度差を感じたわけですが、間違いだろうか。

その後、1分たたないくらいでの失点に、失笑して、あの感動っぷりに納得したりもしましたがね。

なんか、小学生チームがプロチームから(ガチンコ勝負で)1点取ったくらいの勢いを感じて、なんだか、ガンバがあわれに感じたわけです。

そんなものなのかもね。代表の試合観ても、相手にパスするシーンをよくみるし。


もう、そんだけ弱いなら、強化プランとして、小中学生位の(オリンピック競技で言う)強化指定選手を数年、南米のがっついたところに放り込んでしまえばいいのに…。尋常じゃない、(いろんな意味での)強さを身につけて帰ってくるんじゃないだろうか。

もしくは、プロ資格を得るために、どこか、協会が指定する国のプロチームで○時間以上試合で働いた事、とかさ。FWなら○点以上とった、とか。八百な臭いがするけどね。

こないだ知ったけど、J1とJ2両方とも18チームくらいあるんだってね。日本のクラブチームが弱小だって言うなら、増やしてどうすんだか。すごいなだらかな山ができるんじゃなかろうか。はぐれメタルくらいな、さ。いっそ、半分位を外国人だけでできたチームにしちゃえばいいんだ。そしたら、生き残るのに必死になる日本人も出てくるんじゃ…、の前にふてくされたり、客離れにつながるのか。

まあ、勢いで適当な事を書いちゃったりしたけど、言いたい事は、あの実況の人の担当する試合はもう観たくない、ってこと。

You じゃなくて Xerox の方の人は、悪いヤツだと思うんだ。

最後、You が風船を掴んだとたんに、シーソーからおりてる。これ、You がおりてきたときに、ものすごく膝が痛いと思う。

刃牙の軍人みたいな、特殊な着地法でも極めてたりするんだろうか…?最後、普通に娘と笑ってるしなぁ。

なんだか、あの CM を観るたびに、膝がうずいてしょうがない。

ZendFramework と Smarty

ZendFramework で Smarty を使うために一苦労したのでそのメモ。

アクションコントローラごとに Smarty を使うための何かをするのは嫌なので、最悪フロントコントローラごとでどうにかできないか、という方向で対応策を調べていきました(ちなみに、利用している ZendFramework は 2008/12/14 現在の最新安定板である 1.7.1 です)。

まず、なにかしらのテンプレートエンジンを組み込むためには、ZendFramework 用のインターフェースを実装してしまえば、対応させる事が可能になる事が分かりました。
53.3.2.2. Zend_View_Interface を使用したテンプレート(Zend_View_Smarty)

そして、『自動的にビューオブジェクトをコントローラに登録してくれる』ヘルパが用意されており、これはデフォルトの挙動である事が分かりました。
10.8.4.7. ViewRenderer

これで、やりたい事が簡単にできる事が分かりました。以下は、Smarty を利用するための記述を含んだフロントコントローラのソースです。ここで設定するものなのかよく分かっていませんが、とりあえず簡単に済ませるためにここにしておきました(ZF のドキュメントは必要な部分しか見てません)。

実は、これは、すごく不毛なデバッグ作業を経ての結果だったりします。というのも、当初、Zend_View_Smarty のコンストラクタや、setScriptPath メソッドを使って、Smarty の $tempmlate_dir を設定していたわけですが、どういうわけか "unable to read resource: " なエラーメッセージが出てしまいます。

あれこれとプリントデバッグで Smarty の処理を追いかけてみたところ、$template_dir がこちらで指定したものではないものになっていた事が分かりました。どこでそうなったかまでは調べてません。ZF 側の規約のようなものだと思ったので、素直に、そのパスにテンプレートを移動して対応しました。

標準のビューを使う限りは、コントローラディレクトリと同じ階層の "views/scripts/:controller/:action.phtml" がテンプレートパスになりますが、Smarty を使った場合は、scripts ディレクトリを抜かしたパス("views/:controller/:action.:suffix")になる様な感じらしいです。

さて、正直、Symfony なり CakePHP なり Ethna なりの既製品を使った方が簡単だった気がしています。ZF を使ってしまったせいか、無駄に自作もの(車輪)が増えている様な…。


んー、なんだか、Ruby 好きになってきた。自分の好み的に、読みやすいし書きやすい。というか、半年以上 Ruby メインで働いてきたせいで、Ruby でやれる事を PHP に求めてしまいますね。PHP でのやり方をさっぱり忘れています。

get_called_class って、5.3 からなんですかね。「これだっ!」って小躍りしたら、"(No version information available, might be only in CVS)" って…。

"php -a" でヒストリって使えないんですかね。readline の設定次第とかなのかな。

とまあ、久方ぶりの PHP に想像以上に苦戦している今日この頃です。

なんだか、よくわからない。

基本的に、クライアントとサーバの文字セットを同じにして扱う事しかしてこなかったので、それらを別にして skip-character-set-client-handshake しないケースでレプリケーションがどうなるかを、真剣に考えた事がありませんでした。

そういうケースでも、レプリケーションは問題なく行われる(マスタと同一の状態を保てる)のでしょうか。

例えば、以下の様な場合。

client(latin1)->data(utf8)->server[master](utf8)
server[master](utf8)->server[slave](utf8)
relay-log(utf8)->server[slave]

latin1 な client から utf8 な文字列を含む SQL クエリを utf8 な server[master] に送信。

skip-character-set-client-handshake を有効にしていないため、 server[master] であれこれする時に uf8 の文字列を latin1 から utf8 に変換する(from_latin1_to_utf8(str_utf8)なイメージ)。

server[master] のバイナリログには、変換される前の、client から送信されたコマンドそのままが記録される。

レプリケーションを行っているため、server[master] のバイナリログを server[slave] が受け取り、リレーログに書き込む。

server[slave] のリレーログは、server[master] のバイナリログと同じ。

server[slave] の SQL スレッドが、リレーログに記録されたイベントを実行する(ステートメントベース)。

イベントを実行するときの character_set_client および collation_connection および collation_server は、server[slave] のグローバル変数が利用される。

という流れを想像していますが、大分嘘がある様な気がします。

まず、バイナリログへの記録には、client-server 間の文字セットの違いに起因する変換処理が介在せず、クライアントから送られたデータそのままを記録する、というのが本当か知りません。イベントに伴うセッション変数の値を記録していたりするのは知っているので、多分、これでいいだろうとは思っています。が、ドキュメントを確認していません。

リレーログに記録されているイベントを実行する際に、client-server[master] 間で使われた文字セットの関係は、復元されるのでしょうか。されない場合、client-server 間の関係で言うと、それぞれどのような値が使われるのでしょうか。リレーログのイベント実行は、client-server の様な関係で実行されるわけではなかったりするのでしょうか。

ちょっとだけ、ソースコードを読んでみましたが、exec_relay_log_event(...)からset_slave_thread_default_charset(...)にたどり着いて、そこから先がよく分かりません。グローバルな文字セットを標準で使う事は何となく分かる気がしますが、ログに記録されているセッション変数を復元してそれを使うのかどうかが分かりません。ちゃんと読めば分かりそうな気がしますが、本当にちょっと見ただけの状況です。

公式ドキュメントを読んだら、この件に関する記述があったりしますかね。実験で挙動を見れば、どうなるかは分かりそうですが、それはそれとして、仕様的な話を知りたいところです。まずは、公式ドキュメントのレプリケーションやバイナリログ、文字セットに関する部分を一通り読むところからスタートでしょうか。

と、まあ、そんな感じで、さっぱりです。

ひとまず PHPSpec

ZendFramework にもテストフレームワーク的なものがあるっぽいけど、とりあえず PHPSpec で。
PHPSpec リファレンスマニュアル

コントローラのテストなりをする時にどうなるか分かりませんが、とりあえず自作ライブラリに関しては PHPSpec でやっとこうと思います。

RSpec とは大分違い、Describe*なクラス名や、itShould*なメソッド名を強制され、個人的には魅力半減といったところです。まあ、そもそも PHP なので、その辺はあれでしょう。大事なのは、BDD といいますか、*Spec でテストができればいいわけです。

ただ、やっぱり、スペック名(でいいんでしょうか?)が日本語で書けないのが…。

(番号付きの)ソケットファイルは作成できているのに、エラーになるので、待ち時間を超えて処理が進んだりしている様な気がしたり。

(待ち時間以内に)ソケットファイルが作成できなければ、(ソケットファイルを読もうとする事無く)エラー終了する様に見えますが、場当たり的に対応したいので、待ち時間をのばしてみる事にしました。

63    10.times do
64      sleep 1
65      break if (ready = File.exist?(TrackerSocket) && File.exist?(listener_socket(0)))
66    end

"sleep 0.5"を"sleep 1"としておきました。0番のソケットファイルが見つからないというエラーばかりだったので、多分ここかな、と。

なんとなく、エラーに出会わなくなったので、ひとまずはこれで様子見です。


大して意味は無かった気がしてきた…。

Redmine を使って、個人的な案件管理を始めました。

さくらの共用レンタルサーバで動かしているわけですが、CGI だとイライラしてしょうがないので、gateway.cgi というものを使っています。

Apache のエラーログが見れず、使い始めるまでにあれこれ苦労しましたが、無事使える様になっています。が、CGI とは別の意味でイライラしてしょうがありません。

5割くらいの確立で、500エラーになります。どうも、ソケットファイルが見当たらないためにエラーとなる場合があるようです。

ライフタイム(?)がすぎて、ソケットが消えるときにリクエストがきて、あれこれなるんでしょうか。上手く死ねてないのかな?詳細は追いかけていません。

CGI に戻す決意が固まる程のイラつきでは無いので、誤摩化しながら使っていますが、困ったものです。

やっぱ、そろそろ専用サーバのひとつでも使わないと駄目かもしれませんね。EC2とかがいいのだろうか。

久方ぶりのPHP

とある案件が舞い込んできて、相手都合でPHPで実装する事に。

アプリケーションをPHPで実装するのは、9ヶ月ぶりくらいでしょうか。なんだか、ワクワクしますね。まだ、1行もコード書いてませんが。むしろ、書いてないからこそ、(変な意味で)ドキドキするのかもしれません。

かっちりしたフレームワークを学習する気力がわかないので、軽めのZendFrameworkでも使おうと思っています。要求はさっぱりしたものなので、ちゃんと使った事がないZFでも特に問題ないでしょう。

DBマイグレーションの仕組みや、BDD(Rubyで言うRSpec)が無いのが気がかりですが、まあ、複雑なアプリケーションではないので、そもそも不要だろうと思います。spec 慣れしている今、xUnit を書いたときにどんな気分になるかよくわかりませんけど。

さて、矢印ライフが始まるわけですよ。$記号と矢印のめくるめく世界の幕開けですね。

プロフィール

このアーカイブについて

このページには、2008年12月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2008年11月です。

次のアーカイブは2009年1月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。