progの最近のブログ記事

先日からhiphop-phpをいじってたんですが、ビルドを通していざ動作検証、で全然動かないことが多々ありましたもので。

http://wiki.github.com/facebook/hiphop-php/running-hiphop
Running HipHop - hiphop-php - GitHub

最初、動作検証用に用意していたphpファイルはhiphop-phpのソースディレクトリツリーの外に置いていたんですね。自作のファイルをソースパッケージ内に置く訳にもいきませんでしたので。そしたら、

running hphp...
creating temporary directory /tmp/hphp_gVYmhr ...
parsing inputs...
parsing inputs took 0'00" (1 ms) wall time
pre-optimizing...
pre-optimizing took 0'00" (0 ms) wall time
inferring types...
inferring types took 0'00" (0 ms) wall time
post-optimizing...
post-optimizing took 0'00" (0 ms) wall time
creating CPP files...
creating CPP files took 0'00" (85 ms) wall time
compiling and linking CPP files...
CMakeFiles/program.dir/sys/dynamic_table_file.no.cpp.o: In function `HPHP::invoke_file(HPHP::String const&, bool, HPHP::LVariableTable*, char const*)':\ndynamic_table_file.no.cpp:(.text+0x29b): undefined reference to `HPHP::pm_php$__$__$hello_php(bool, HPHP::LVariableTable*)'\ncollect2: ld returned 1 exit status\nmake[2]: *** [program] Error 1\nmake[1]: *** [CMakeFiles/program.dir/all] Error 2\nmake: *** [all] Error 2\n
compiling and linking CPP files took 0'45" (45426 ms) wall time
hphp failed
running hphp took 0'45" (45654 ms) wall time

こんな感じで、どうやら解決されないC++シンボルが発生するみたいだったんですな。

ていうかHPHP::pm_php$__$__$hello_php()って関数(orメソッド)名はどこから来てるのさ、といろいろいじくっている間に、hphpに渡していたファイルの名前=hello.phpをtest.phpとかhello2.phpとか色々いじってみると...、おろ、関数名も変わるじゃないですか。お。じゃあこのファイルの場所を動かしたらどうなるよ、ということでさらに色々試してみたら、カレントディレクトリに持ってきたら普通に動作した。

で、うまく動作したときとだめだったときを比較してみる。すると、ダメな時はphpディレクトリ配下が空っぽなのですよ。生成されたC++ファイルの構成を正常に生成されたものと比べれば一目瞭然なのでござるよ。

hironobu@claire:~/Projects/hiphop-php/src$ ls -l /tmp/hphp_dMpt9D/php
合計 12
-rw-r--r-- 1 hironobu hironobu 794 2010-07-01 22:14 hello.cpp
-rw-r--r-- 1 hironobu hironobu 419 2010-07-01 22:14 hello.fw.h
-rw-r--r-- 1 hironobu hironobu 479 2010-07-01 22:14 hello.h
hironobu@claire:~/Projects/hiphop-php/src$ ls -l /tmp/hphp_gVYmhr/php
合計 0

このhello.phpをディレクトリ掘って、hiphop-php/src/HELLO/hello.phpみたいに配置してみると、

hironobu@claire:~/Projects/hiphop-php/src$ ls -l /tmp/hphp_yW3fOW/php/
合計 0
drwxr-xr-x 2 hironobu hironobu 53 2010-07-01 01:53 HELLO
hironobu@claire:~/Projects/hiphop-php/src$ ls -l /tmp/hphp_yW3fOW/php/HELLO/
合計 16
-rw-r--r-- 1 hironobu hironobu 6927 2010-07-01 01:53 hello.cpp
-rw-r--r-- 1 hironobu hironobu  465 2010-07-01 01:53 hello.fw.h
-rw-r--r-- 1 hironobu hironobu  581 2010-07-01 01:53 hello.h

こんな風になったでごわす。要は、hphpに引数として渡すphpファイルのパス指定が、カレントディレクトリより上位を指すと、生成されるファイルツリーのphpディレクトリ配下をはみ出してしまうためビルドに失敗するということのようです。つまり。てかこのhello.cppとかと同じファイルが、よく見ると/tmp直下にも生成されていた不思議。しかもダメだったときのファイルツリーとほぼおなじタイムスタンプで。そりゃ、どうもならんですわ。

ここ一週間くらいこれに振り回されたでござる。ぷすん。

で、一連のベンチマーク結果のグラフ化にHighchartsを使ってみたんですが、この棒グラフ表示でおかしな点があったので一ヶ所自分で手を入れたのです。

http://www.highcharts.com/demo/?example=bar-basic&theme=default
Highcharts Demo Gallery

具体的に言うとこれですね。

Year 1800/1900/2008とある右上の凡例の順番と、Africa,America,...とある各グループの棒グラフの並びを見て頂きたい。凡例の方は1800の青、1900の赤、2008の...何色だ?これ?^^;;(color panel使って見たら「オリーブ色」らしい)という順番になってるのに、棒の順番は逆になっている。ちゃんとグラフを読めば分かるんだけど、並びが違うことで感覚的におかしな気分になるなと。

パラメータで調整して直るのかもしれなかったけど、突き止めきれなかったのでコードを弄って直すことにしてみました。最新版の1.2.5を元にhighcharts.src.jsに手を入れて、ClosureCompilerを通したのを使ってます。万一これでおかしくなっても大丈夫なようにオリジナルはオリジナルで残しておきましたよ。

--- ./highcharts.src.js.orig	2010-04-13 14:43:26.000000000 +0900
+++ ./highcharts.src.js	2010-04-19 02:33:36.199575268 +0900
@@ -4200,7 +4200,7 @@
 	
 	// Initialize the series
 	//initSeries();
-	each (options.series || [], function(serieOptions) {
+	each (options.series.reverse() || [], function(serieOptions) {
 		initSeries(serieOptions);
 	});
 	

まだ生きてるよ!(挨拶)

ご他聞に漏れずうちもSnow Leopard入れましたが、Growlが現時点(1.1.6)でどうやらまだ対応してない(公式曰く1.2まで待ってけろとな)、というかx86_64用バイナリを持ってないようですね。

IntermezzoがGrowlを使用しているので、本体のx86_64対応を進めとこうと思ってもビルド時にリンクさせておくと当然エラーが出て怒られる。Growlが動かなくてもかまわないからとりあえずx86_64動作時にもGrowlの如何に関わらず動かしたいと思ったので、実行時の動的ロードに切り替えよっかってしてみたんだけどなかなか動かないからアレッと思ってギアいじったっけロー入っちゃってもうウィリーさ(何)

http://growl.info/documentation/developer/implementing-growl.php?lang=cocoa
Implementing Growl support in your Cocoa Application

ここに書いてあったのにね。

この"Using Cocoa, you can use the following code snipped..."を参考に少し修正したのが下です。

    Class bridgeClass = nil;

    NSString* growlPath = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:@"Growl.framework"];
    NSBundle* growlBundle = [NSBundle bundleWithPath:growlPath];
    if (growlBundle && [growlBundle load]) {
        // bridgeClass = [growlBundle principalClass];
        bridgeClass = [growlBundle classNamed:@"GrowlApplicationBridge"];
        
        if ([bridgeClass isGrowlInstalled] == NO || [bridgeClass isGrowlRunning] == NO) {
            // Growl本体がインストールされてないか、動いてないよ
            return;
        }
        
        [bridgeClass setGrowlDelegate:self];
    } else {
        // Growlフレームワークがない、またはロードできないよ
        // x86_64の場合はここに来るよ
        return;
    }

    // ok

GrowlApplicationBridgeクラスがビルド時のリンクで解決できないので、classNamed:メソッドを使いバンドル(フレームワーク)から読み込んでリンクする方向に倒して、ようやく動くようになったとです。Growl.frameworkのInfo.plist読む限りでは、Principal ClassはGrowlApplicationBridgeクラスなので、classNamed:の代わりにprincipalClassメソッドでも行けるはずだけど、将来に渡ってどうかは分かんないのでとりあえずclassNamed:で名指しにしてます。まあそんときゃGrowlApplicationBridgeクラスだってdeprecatedになってるかもしんないけどねー。

まあ、Growl 1.2が出れば多分それで無問題なんだろうけどねー。

(*´・ω・)(・ω・`*)ネー

右下端に何かありますが、それです。最初Flash版で入れてみようとしたんですが、サイズ的にどうもしっくりこないのと、デザイン的に浮き気味だったのでやめにしました。

http://developer.apple.com/iphone/program/sdk.html
Get Ready for iPhone OS 3.0 - iPhone Developer Program

まだあんまり中身見通してないのでアレですけども。とりあえず個人的に欲しい機能がまだ来ないっぽいのが(´・ω・`)です。はい。

あとはかつて使ってたiPod Touch(16GB)を手放さずにとっとけばよかったな、とも。

Intermezzo 0.9.0リリース

| コメント(0) | トラックバック(0)

ひさびさのIntermezzoのバージョンアップです。

  • キーワード機能を実装しました。
    "Preferences"パネルで"Keyword"タブを追加しました。ここでリストに追加すると、強調表示およびキーワード出現時にGrowlによって表示されます。
  • Growl機能復活しました。

こんなところで。次いくとしたら0.9.x->0.10.0かなあ。1.0に持っていくまでにもう少しかかるかもです。

Intermezzo 0.7.0 リリース

| コメント(0) | トラックバック(0)

Intermezzo 0.7.0リリースしました。...といってもやっとbetaなので、取り扱いにご注意ください(何)

http://trac.foursics.jp/intermezzo/
Intermezzo trac

  • 今のところ10.5(Leopard)専用ですが、10.4以前への対応は検討中です。
  • ドキュメントは今作ってます。
  • メニューに余計なのとか入ってるっていうか残ってますけど、気にしないでください。
  • バグレポートや機能要望などはtracのチケットで受けられるようにしますのでそちらにどうぞ(ここでもいいけど^^;;)

MacOSX上でネットワークを扱うプログラムを書く場合、やり方はいくつかある。

  • ソケット
  • NSStream
  • NSURLConnection
  • 分散オブジェクト環境

あと、CarbonベースでもよC言語向けのが欲しければCFNetwork、あとBSDソケットとほぼ同等だけどCFSocketという手もある。まだ他にもあるかななな。

http://www.geekpage.jp/programming/macosX-network/
Geekなぺーじ : Mac OS Xネットワークプログラミング

まあ、NSURLConnectionなんかはURLベースなので「ネットワーク」というには大分限定的・局所的だし、分散オブジェクト環境に至ってはCocoaアプリケーション同士でないとほとんど使いこなせない。汎用性ではソケットに勝るものは無いでしょう。ただ、状況に応じていろんな選択肢があること、これを常に心に留めておくことはとっても重要。

あと、Cocoaではソケット・ファイルディスクリプタをwrapすることのできるNSFileHandleもあるので、ぜひこれらをフル活用していきたい。通知(NSNotification)やデリゲートの仕組みを元に、メインループからの非同期的読み込みの機構も実装されているので、これを使った方がCocoa GUIアプリケーションとしてより自然な挙動を実現することができる。

確かにソケットでよく使うFIONBIOやselect()/poll()などはそのまま適用可能だけど、UNIX系由来のコードを出来るだけそのまま動かすといった明確な意図に基づいて扱う場合以外は、それが有効に効力を発揮する局面はあんまり無いように思う。(≒GUIを持たない、純粋にC言語でmain()からがりがり書くようなケースも含む。ただそれでも、結果的にCocoa/Carbonに乗っておいた方が楽になれることも結構ある)

まあ、NSStreamとNSFileHandleさえあればわりとごはん3杯くらいいけます。はい。

http://developer.apple.com/documentation/Cocoa/Conceptual/Streams/Streams.html
Stream Programming Guide for Cocoa: Introduction to Stream Programming Guide for Cocoa

http://developer.apple.com/documentation/Cocoa/Conceptual/LowLevelFileMgmt/LowLevelFileMgmt.html
Low-Level File Management Programming Topics: Introduction to Low-Level File Management Programming Topics

今週のObjective-C重箱の隅

| コメント(0) | トラックバック(0)

http://www.atmarkit.co.jp/fcoding/articles/objc/02/objc02a.html
一番初めのObjective-Cプログラム - @IT

ものすごぅく細かいことだけど、ブコメにも出ているのに割とスルー気味なのが気になったので書いちゃう。

  • alloc/retainとreleaseの対応付け

    他の点は見解の違いや記述意図次第で変わる話なので、ぶっちゃけどうでもいいと思うけど、これに関しては最低限きちんとやった方がいい。

    Cがmalloc()に始まりfree()に終わる言語であるように、Objective-Cもメモリ確保が非常に大きな意味を持つ。私がこの言語に触れたときはその最初の一歩(から少し踏み出したくらいだったかもしれないが)で、alloc、retain、releaseの組み合わせについて散々言及された文献にぶち当たらされたものだった。

    最初の一歩なので、それぞれの意味や規則についていろいろと説明するのは後回しでかまわないのだから、せめてサンプル内でもreleaseするくらいはして欲しかった。訳分からないうちから癖づけるくらいしないと、retain/releaseが幾重にも折り重なる現実のObjective-Cのコードとやっていくのはちょっと、いやかなり難しい。まあ、最近はGarbage Collectionも入ってきてはいるけど、それが全面的に受け入れられるほどまだObjective-Cの世界はシフトしていってないし。

  • クラス個別のヘッダファイルのインポート

    これはどうなんだかな。最初なんで、使用するクラスを名指しでインポートして見せたいっていう意図なんだろうけど、通常は#import <Foundation/Foundation.h>とか#import <Cocoa/Cocoa.h>とか、フレームワーク単位で用意されたヘッダファイルがあってそっちを使うことが多いと思うなあ。でそいつをプリコンパイルヘッダに持ってくとかね。あんまり個別にインポートしてばかりいるとそれだけで1画面分とかなってしまうので、一般的にはちょっとおすすめできない。まあ、考え方次第だと思うけど。

  • ヘッダファイルさらに

    Objective-Cは良くも悪くも根っこがCなので、ヘッダファイルをどのようにインポート(Cではインクルード)するかを一応ちゃんと考えとかないといけない、と思う。まあ、Cではかつて同一のヘッダファイルに対する多重インクルードを防ぐ仕組みが言語仕様上無かった頃の名残であって、#importでそこを解決してるんだからいいじゃない、という考え方もあるにはあるけど、しなくてもいいインポート/インクルードを防ぐことでコンパイル時間をコンパクトに保ちましょう、という主張は(この程度の極小規模のコードではあるが)まだ説得力があるはずだ。

    従って今回のケース、stdio.hのインポート位置は明らかにSinger.mの方だと思うし、Song.hについても同じくずらすことはできる。まあ、Song.hについては@class使ったりする必要があってさらに説明が増えることになるから、やんない方がいいか。まあ、そこをid型使ってごにょごにょ、っていうこともできるけどね。

  • @implementationの後ろは

    クラス名だけでok。": 親クラス名"は要らんすよ。

Objective-Cや、Perl/Python/PHP/RubyいわゆるLL系言語はみんなそうなんだけど、ああ、JavaScriptもそうかな。

私はわりとリファクタリング大好きでそのおかげで開発作業が遅滞してしまうという本末転倒な馬鹿をよくかますのだが(うーん)、関数名を変更したり引数の数や型を調整しようとしてCでよくやっていたような、関数宣言を先にいじってしまってからコンパイラを通すと、warningで呼び出し部を一網打尽に拾いだすような手段が取りにくくて結構こまる。Objective-Cはまだ付いてきてくれるけど、id型が絡むととたんにゆるゆるじゃし。

Eclipseぐらいのリファクタリング快適性がXcodeに載ったらうれしいなー。いや、使いこなせてないだけだったらごめんなさい。ぎゃふん。