いけむランド

はてダからやってきました

funcall

funcall は任意の関数の前後に callback を追加することができる PECL である。


使い方は以下のとおりである。



実行結果は以下のとおりである。

% php ./funcall.php 
pre require_once (/Users/fd0/.phpbrew/php/php-5.3.15/lib/php/OS/Guess.php)
post require_once (/Users/fd0/.phpbrew/php/php-5.3.15/lib/php/OS/Guess.php)

Eclipse から Cygwin を起動する

Eclipse を全画面で使っている時に Cygwin のコマンドを叩こうと思って、前面に持ってくると、今度は参照しようと思ってた領域に出てきてしまって、マウスで Cygwin のターミナルを移動させる手間が発生して、ストレスで(」・ω・)」うー!(/・ω・)/にゃー!ってなるのが嫌だったので、Eclipse に組み込めないかなと調べた。

まず cygwin の sshd を起動する。


次に Eclipse にターミナルを入れる。


ターミナルから localhostssh で接続したら簡単にできた。


f:id:fd0:20120804163615p:plain

SplObjectStorage について考えてみた

PHP では array はキーに object をとることができない。

array や object は、キーとして使えません。 キーとして使おうとすると Illegal offset type という警告が発生します。


そのため、キーに object をとることができる標準クラスがある。

SplObjectStorage クラスは、オブジェクトをデータに対応させたり、 データを渡さずオブジェクトセットとして使用したりします。


けれども、このクラスは個人的に気持ち悪い。

それは Map としても Set としても使えるということである。

元々 Map の実装であるが、キーの object に対して、値を null で保持することで Set を実現しているらしい。

あと、Map として使う場合に foreach も気持ち悪くなる。

$map = new \SplObjectStorage();
$key1 = new stdClass();
$map[$key1] = 'value1';
$key2 = new stdClass();
$map[$key2] = 'value2';
foreach ($map as $key => $value) {
  var_dump($key, $value);
}


これを実行すると以下のような出力となる。

int(0)
class stdClass#2 (0) {
}
int(1)
class stdClass#3 (0) {
}


キーと値をきちんと舐める場合は以下のように書かないといけない。

foreach ($map as $value) {
  var_dump($value, $map[$value]);
}


ちなみに key() をオーバーライドして object を返すように定義すると、上述の通り Illegal offset type と怒られる。><

オレオレ実装で Map として気持良く使わせたい場合にはどうすればよいだろうと考えてみたら、each() メソッドをつくってあげるのが良いのではないかと思った。


新・unable to remap が rebase で解決しなかった時の話

近頃のパッケージツリーでは setup.exe で新しい lib*.dll がインストールされると、ほぼ確実に autorebase が postinstall で動いてしまい、どの都度 unable to remap 地獄に突入することになる。

 

前回 offset がぶっ壊れた DLL を再インストールして、丁度良い offset を探せば良いと書いたが、どうも rebase 再実行はしなくても動くっぽいことがわかった。

 

 というわけで unable to remap が発生したら

  • libgcc1
  • libiconv2
  • libncursesw10
  • libreadline7

を再インストールしてやれば少なくともシェル起動まではいけるはずなので、あとは必要に応じて、怒られる DLL を再インストールしてやれば、普通に使えるようにはなるはずである。

phozzil (1)

探してみたら IO_Bit というのもありました。

string をがっつり渡して、integer などに変換するインタフェースっぽい。resource から string にするまでは関与しないということらしい。


以下、これらを踏まえてのインタフェースについての考察を述べてみる。

string ≒ byte[] ?

PHP は基本的に resource からの入出力データインタフェースが string である。そのため、バイナリデータを扱うためには string に対して pack / unpackord を使うのが定石っぽい。

PHP の文字列は言語仕様を見ると Java における byte[] に近い *1 とは言え、ストリームからのデータが string を経由することを利用者が意識しないといけないのはあんまりスマートじゃない気がするため、resource を渡したオブジェクトから直接 readXXX したら、その型のデータで得られるインタフェースが望ましいのではないかと思っている。(つまり java.io っぽいやつ)

エンディアン

バイナリデータを扱う場合に出てくるもう一つの問題がエンディアンで、これもライブラリによっていろいろ扱いが異なっている。

java.io ではビッグエンディアン決め打ちになっているし、上述の IO_Bit や php-reader では read メソッドの末尾に LE/BE という suffix があり、呼び出し毎に利用者が指定するようになっている。

せっかく LE/BE があるのはありがたいとは思うけど、逆にストリームの中で頻繁にエンディアンが変わる場合があるのかも気になる。コンストラクタでデフォルトのエンディアンを指定しておけばいいのではないかと感じる。

phozzil (0)

そろそろなんかちゃんとしたコードを公開しないとプログラマとして淘汰されるなあと強迫観念みたいなものを感じてる今日この頃です。


ここ一年くらい業務でログ集計系のコードを書くことが多く、その際に毎回、ログをパーズするためのプリミティブなファイルシステム関数の一連のコードをおまじないのようにコピペすることに抵抗があったため、java.io みたいなクラス群にまとめられないかなと思った。

既にこの要求を満たすものがあれば、それを使えばいいわけであるため、調べてみると当然ながら既に同じようなことを考えている人はいた。


前者はまさに java.io のインタフェースに沿っているなあという印象で、後者はバイナリデータ周りの実装がきちんと整っている。ただし、いずれも名前空間を使っていない。

とりあえずこの 2 つのいいとこどりをしたものを書いてみるというところから始めてみることにしてみようと思う。


ちなみに repo はつくってあるけど、中身はまだない。