PHPのAPI DOC生成にDoxygenも使うことにした

Doxygen

経緯

  • 以前から一部のリポジトリで phpdoc がメモリ不足で落ちて困っていた
  • Doxygen は何年か前にも試していたが、PHP の解釈がイマイチで採用を見送っていた
  • 今回試してやはりイマイチだったが、いくつかの問題を我慢すれば使えそうだったので、メモリ不足で落ちるよりマシと判断して使い始めた

現在稼働しているバージョンは 1.5.6

動かせるようになるまで

最初は

  • 落ちる
  • 返ってこない

ファイルが後を絶たなかった。どうしたか。

EXCLUDE しまくる

まずはこれが基本。設定ファイルの中に EXCLUDE, EXCLUDE_PATTERNS の設定があるのでこれを利用してひたすら問題になるファイルを除外しまくる。話はそれから。

  1. とりあえず EXCLUDE
  2. 一つずつコメントやコードの構造を直して落ちないか試す

以上をくり返すことでほとんどのコードを扱えるようになる。

※ Warning はとりあえず無視しして徐々に対応していく。

やばげなパターン

if () {
  ...
}

でコード全体を囲んでいると doxygen が返ってこなくなりやすいみたい。

とは言え必ず返ってこないかというとそうではなく、コメントの書き方が正しくない場合に返ってこなくなる可能性が高い、という感じらしい。

コメントの書き方ミスにはとても厳しい

phpdoc と違ってかなり厳しい。少なくとも phpdoc 的には大きな問題でなくても Doxygen ではダメなケースは多い。ただし本当に問題になるのはやはり

正しくないコメント

なので、普段からちゃんと書けている場合はとりあえず移行そのものはそれほど大変ではないと思う。

対応してるタグは少ない

phpdoc に比べると対応するタグがだいぶ少ない。ただし、

  • シンプルでよいと思うことにする
  • ソースにリンクを張れるのである程度解釈が変でも直接読ませることでよしとする

で、乗り越えられる :-)

切り替えて使う

複数のプロジェクトのコードからドキュメントを自動生成する

で述べたように phpdoc の生成は自動化しているのだが、この中でドキュメント出力先は都度クリアしてから作業を始めている。このとき削除には

rm -r *

を使っているので、ドキュメント生成先に .doxyfile というファイルが用意されていたら doxygen で、そうでなければ従来通り phpdoc で処理することにした。1

これで、全リポジトリで一気に Doxygen 対応をはかる必要がない。

よさげな設定

いろいろ試行錯誤した結果と default の diff を出してみた。たぶん Java っぽく振るのがいいんだと思ってるんだけど、どうなんだろう。

結果

  • Doxygen の PHP 対応は今もやはりイマイチ
  • メモリ不足で API DOC を生成できないリポジトリがなくなった
  • API DOC 生成のスピードは10倍以上に跳ね上がった
    • API DOC 生成に使っているサーバの仕事を増やせる
  • Windows 版もあるので、気軽に何回もドキュメント生成を試すことができる
    • ドキュメントの品質向上に繋がるかも
  1. いちばん上の階層のドットファイルは rm -r * では削除されない。 

revert, reset, rebase, ...

例によって自分用のメモ。間違ってる場合はツッコんでください。

「svn revert」は「working copy の変更をなかったことに」してやり直すために使う。update でコリジョンが起きた場合にこれを使うと問題なく repository の状態に追随できる場合が多い。

「git revert」はコミットそのものをなかったことにする。はずだったような気がしてたんだけど、「コミットそのものをなかったことにするコミットを行う」。言い換えると revert しましたという記録を残す。

git で svn revert 相当のことをやりたい場合は

  • git checkout
  • git reset

のどっちかでいいような気がする。こんな感じに使う。

git checkout BRANCH
git reset COMMIT

git reset の動作は3種類。

–mixed
working tree には触れずに index の commit をなかったことにする。デフォルトの動作。
–soft
index も working tree もまったくタッチしないって言ってるような気がするんだけど、自分が試したら見事に修正分がぶっ飛んだ。意味が分からん。怖くて使えん。
–hard
こっちが本当は自分の作業を全部ぶっ飛ばしてしまう動作のはず。

あちこちでいろんな人が言ってるけど git ってほんとよく分からん。根本的な考え方が他のツールと合ってない部分が多く、使う言葉が違うので当てずっぽで作業すると痛い目にあう。もちろん互換性を捨てたおかげで良くなっている点もあるんだろうけど、移行するにはハードルが結構高い気がする。

ということで最近では凝ったことする前に Mercurial にも突っ込んで意図しない動作をしても元に戻せるようにして作業している。git は便利だがなんか怖い。

ただ、Emacs の vc-mode で vc-revert-buffer すると svn だろうと git だろうと同じように扱える。一回に一つのファイルしか revert できないけど、すでに Emacs と vc-mode を使えている人はこれ使うのがいちばん確実だと思う。vc-mode がいつから git に対応しているのか細かことは知らないけど、たぶん 21 は NG で 22 は OK だと思う。

rebase はなんかよく分からなかった。名前がちょっと似ているだけでまったく別な機能らしい。

CentOS 初挑戦で yum リポジトリに悩む

CentOS を入れてみた。

全然パッケージないじゃん。みんなこんなんで仕事できるの?できないよね?

例えば 4.5 では nkf もない。5 にはあるけど。エンタープライズな皆さんはそんな雑多な処理はなさらない? 自動判定なんかに頼らずに iconv 使うのが常識? うっそーん。もしかして時代は今 Perl + Encode.pm ? うっそーん。まさか php + mbstring + encoding_transfer で文字コードなんて気にしちゃいない? うっそーん。

でだ。

パッケージ探訪の旅に出るわけですな。面倒くせぇなぁ。ports や今の Debian なら欲しいものはほとんど全部手に入るのに。1ざっと調べると

  • CentOS の配布物なんだけど標準の yum リポジトリの設定では enabled になっていない centosplus
  • EPEL (Extra Packages for Enterprise Linux)
  • RPMforgeDAG, Dries, freshrpms が参加してるっぽい。)
    • rssh とかこの辺で手に入る
  • Fedora extras(適当な Fedora mirror の中の extras)

cf.

を使うのがメジャーな感じですか。(ミラーの選択には netselect であれこれ とか参照していただければこれ幸いにございます。)

他にも @IT:Fedora Coreの非公式リポジトリをyumで利用するには なんて記事があって、Fedora FAQ からリポジトリのリストを取得できるらしい。

ただ一応 RHEL ですよね。デスクトップで使うっちゅーならともかく、公開サーバとして使う場合、どのリポジトリまで使うことにするのか、判断が必要になってきちゃうんですよね。混ぜたら RHEL クオリティは保てないわけだから。(必要ならパッケージ単位でも検証はしなきゃならんのだろうなぁ。)

アップデートポリシーは基本的にリリースバージョンが上がらない限りはアプリのバージョンは固定なのかな? なんかそんな感じだよね? 例えば 4.4 -> 4.5 のときにはアプリのバージョンは上がる可能性があるけど、4.5 の間は変わらない、みたいな雰囲気。(CentOS や最近の RedHat, Fedora はまったく使ったことがないので全然分からないのです 。)

いや今ナニしてるかと言うと、CentOS 4 と 5 の比較をしてるんですが。やっぱ 4 はアレコレ古いなーと思っているところなのです。Ruby も 1.8.1 だし。やっぱ 5 の方がいいかなー。ただ Cent5 にしても PHP は 5.1.6 なのよね。PHP 5.2 で「まとも」と呼んでいいのは恐らく 5.2.3 からなので、そうするとリリースのタイミングからしてこうなっちゃうよね。逆に Cent4.5 だと PHP は 4.3.9 なので、PHP 5 の機能が不要でパッチがちゃんと出るならしばらくこれでいくという判断もアリっちゃーアリだろな。ただ、Ruby 1.8.1 は割と本気で困るけど。せめて 1.8.2 にしてくれればいいのに、やっぱポリシーの都合で上げなかったのかなぁ。(1.8.2 でアレコレ変わりましたよね。)

ところで本題ではないんだけど、今回のこの実験には CentOS 5 から標準で入った Xen を使って domU に Cent5 と Cent4 を同時に起こして確認してみてるんだけど、どっちも virt-install でスコっと入るので拍子抜けするくらい簡単。Xen も初めて2だったけど、僕にもできたよ!3 ただ本当はこの上に Debian な domU も作る予定だったんだけど、なんか手元に Xen カーネルの Debian が立ち上がる機械が余ってなくて断念しちゃった。wakatono さんみたいに debootstrap で手作業? いやいやいや。自分、不器用ですから。(意味が違う。)

※ EPEL は互換性、依存関係で悩むことが少なそう。サポート云々は聞いてみるのがいちばんか。

[2007-10-29 追記] EPEL の記述を追加。これが RHEL 外部リポジトリ的には本命か?

cf. yum リポジトリで特定のパッケージだけを扱う

  1. ports はたまに外れ引くことあるけど^^; 

  2. 厳密にはちょっと違うけど 

  3. console が手元の screen と相性悪くて最初何がなんだか分からなかった。screen てチョコチョコこういう現象に出くわすよね。 

CentOS のネットワークインストール時に URL を間違ってハマる

アホすぎ。何を間違ったかっちゅーと、例えば IIJ ミラーを使ったときに

×http://ftp.iij.ad.jp/pub/linux/centos/5/isos/i386/
http://ftp.iij.ad.jp/pub/linux/centos/5/os/i386/

この間違いでしばらく悩みました。Invalid URL と 404 しか出ないと分からない…。いろいろ試して、images が見つからないとかいうメッセージが出て気がついた。http じゃなくて ftp の方が間違いに気づきやすいかも。

なんちゃってスモールスクリーンレンダリング.user.js

この間のスクリーンショット事件で頭にきたので作ってみた。一応 greasemonkey でメニューから実行できるようになってる。

/**
 * Pseudo Small Screen Rendering
 *
 * @constructor
 */
function PseudoSSR() {
  /**
   * base css
   * @type    string
   */
  this.base_css = "* { margin: 0; padding: 0; line-height: 1.2em }";
  /**
   * body style
   * @type    Object
   */
  this.body = {
    'background':  'white',
    'font':        'normal 100%/1.2 monospace',
    'color':       'black',
  };
  /**
   * container, for making body overflowed
   * @type    Object
   */
  this.container = {
    'width':       '11.5em',
    'height':      '11.6em',
    'overflow':    'auto',
    'border':      '3px inset black',
  };
  /**
   * list block css
   * @type    Object
   */
  this.list = {
    'padding': '0 0 0 1.5em',
  };
  /**
   * list item css
   * @type    Object
   */
  this.list_item = {
    'margin':  '0 0 0 0em',
    'list-style-position': 'inside',
  };
  /**
   * force `a color' blue
   * @type   Object
   * @since  2006-10-30
   */
  this.a = {
    'color': 'blue',
  };
};

PseudoSSR.prototype = {
  /**
   * change html and apply css
   */
  run: function() {
    this.append_base_css();
    this.insert_container();

    var body = document.getElementsByTagName( 'body' );
    this.apply_style( body[0], this.body );
    var container = document.getElementById( 'container' );
    this.apply_style( container, this.container );

    this.apply_style4elements( 'ul', this.list );
    this.apply_style4elements( 'ol', this.list );
    this.apply_style4elements( 'li', this.list_item );
    this.apply_style4elements( 'a', this.a );
  },

  /**
   * append basic css in <style> element
   */
  append_base_css: function() {
    var head = document.getElementsByTagName( 'head' );
    head = head[0];
    var style = document.createElement( 'style' );
    head.appendChild( style );
    var style = head.getElementsByTagName( 'style' );
    style = style[0];
    style.innerHTML= this.base_css;
  },

  /**
   * insert container <div> element
   */
  insert_container: function() {
    var body = document.getElementsByTagName( 'body' );
    body = body[0];
    var doc = new String( body.innerHTML );
    body.innerHTML = '<div id="container">' + doc + '</div>';
  },

  /**
   * apply JSON-style CSS to element collection
   *
   * @since  2006-10-30
   * @param  String ele
   * @param  Object style
   */
  apply_style4elements: function( ele, style ) {
    var node = document.getElementsByTagName( ele );
    var len = node.length;
    for ( var i = 0; i < len; i++ ) {
      this.apply_style( node[i], style );
    }
  },

  /**
   * apply JSON-style CSS to element
   *
   * @since  2006-10-26
   * @param  DomNode ele
   * @param  Object  style
   */
  apply_style: function( ele, style ) {
    var ele_style = ele.style;
    for ( var prop in style ) {
      ele_style[prop] = style[prop];
    }
  }
};

/**
 * launcher
 */
GM_registerMenuCommand( 'PseudoSSR', function() {
                         var ssr = new PseudoSSR();
                         ssr.run();
                       } );

やってることは単に CSS で見た目を変えてるだけ(それも margin とかサイズをいじってるだけ)なので、user css だけでできるんだけど、user javascript になっていれば Gecko ブラウザで適用のタイミングを自分で選べるのでわざわざ JavaScript にしてみました。

ポイントは

  • 自家製なので中身いじりたい放題
  • Opera とか webdeveloper の small screen rendering よりも「ケータイっぽい」

くらいしかないです。

GM_registerMenuCommand() の中身をそのまま素で書いてやれば GeekMonkey を使ってブックマークレットにして Camino で動かせることを確認。CreamMonkey で動かすのには失敗しました。どうやんのか分かりません。

CSS を冒頭で定義しているのでこの辺をいじれば自分の好きなデザインのスモールスクリーンレンダリングもどきが作れます。あと、いきなり body 直下に div#container という要素を挿入するので、すでに container という id を持つ要素があるとまずいです。

margin-* とか font-* とかは DOM バインディングで定義されていないので反映されません。Firefox で試した限りでは fontSize などで定義されているようです。あるいは簡略記法で定義するのが純粋な CSS 上の表記と一貫性があっていいかも。

というわけでもろもろ踏まえてご自由にご利用ください。

lily2 がまだ延びるらしい

近況報告 - てくのーと

実は次の説教講座は lily でいっちゃおうかと思っていた(静的出力に期待大)ので、lily2 のリリースが延びたってことはその分作業を延ばすことができるのでめでたいですな(違

ストレージをスイッチできるようにしておくってのは最近自分もちょっと頭を悩ませているところなので、こっそり参考にさせてもらおうっと。

何も知らないまま PodCasting について想像してみる

まぁそんなわけで、ストリームコンテンツである(と思っている)PodCasting にはまったく興味ないわけだけど、そこかしこで話題になってるのは間違いなくて、先日ついに PodCasting って何?って聞かれたのでちょっと調べてみた。

自分の疑問は以下の通り。

  • それって何に対する言葉なの? データフォーマット? プロトコル? ツール? サービス?
  • 今までのネットラジオと何が違うの?

すると iTunes の説明だの、実態が全然理解できない説明しか出てこない。我慢してその辺の情報を拾い読みすると

  • 登録しておくと更新情報を自動でチェックして音声データをダウンロードしてくれる

ってことはよく言われている。そうか、ダウンロードできるのはネットラジオと違うかもしんない。

  • じゃあ、「音声データを単に HTTP でアクセス可能なところに置いておく」のと何が違うの?

という辺りでハタと思いついた。あーそうか、音声データが置かれたことを通知するのに RSS とか使ってるんだ。で、音声データのライブラリを管理する iTunes みたいなソフトに RSS リーダーが統合されたってことか。そうかそうか blog みたいなインターフェイスで音声データのアップロードと同時に ping を打てば番組情報の一覧や検索に引っ掛けることもできるし、ユーザーはそういう大手の更新情報を使ったり、直接配信されてる更新情報を使ったり、適宜選べばいいんだ。

要するに blog の仕組みに音声データが載るようになっただけか。Pod って言葉は単にキャッチーな要素ってだけかな。まーでも確かに今までのラジオのようにストリーミングさせようと思ったらちょっと大げさな仕組みを用意しなきゃいけないし、面倒だ。なるほど送り手も受け手も楽になってる気がする。ついでに、うまくやれば mp3 だろうと midi だろうとどんなフォーマットにもメタデータを付けられるから、ファイル自体にメタデータを保持する機能のないフォーマットが復権したり…しないか。midi に対応してる携帯音楽プレイヤーなんかないよね。1

それ以前にここに書いてあることはほとんど想像なんで、復権がどうとか言う以前の問題なんだけど、あーこれ画像でも動画でもなんでもいいんじゃん? つーか iPod はもうどっちにも対応してるから、そういう使い方してる人、実際にいるかも。待てよ。iPod とかにこだわらず、使い勝手とレスポンスに問題がなければ Flash でも PDF でもいいんだよな。全部に対応できるプレイヤーはないけど、メタデータにサムネイル埋め込むとかして、とりあえずライブラリを管理するだけならできそう。

これ実はすごい? 気づくの遅い?

  1. 携帯電話は可能かもしんない。 

理解しにくいらしいストリームコンテンツへの嫌悪感

私はストリームコンテンツのほとんどが好きじゃないのです。どうもこれが理解しにくいらしい。

まず、ストリーミングがきらいなんじゃなくて、ストリームコンテンツがきらいということがぱっと分からないらしい。ダウンロードできようができまいがそんなことは関係ないのです。

例えば1分のストリームコンテンツは1分間視聴し続けなければならない。もうね、これがいやなの。音楽とかそうでしょって言うけど、音楽と情報は違うから。早送りすればいい? 映像ならともかく、音声はどこまで飛ばせばいいか、判断できるようになるためには少なくとも1回は通しで聞いておかないといけなくない?

だから同じ情報を含んでいるものなら音声よりテキストの方が断然好き。動画になると情報量を格段に上げることができるので、不自由さの代わりに情報量が豊かになっていれば、まぁ許す。けど、制作コストも高くなるのでそういうコンテンツを制作できる人はそう多くないだろう。

これが情報でなくて娯楽ならそりゃラジオ、テレビ、映画には慣れ親しんでいるわけだから、別にそんなに毛嫌いするほどのことではないんだけど、自分にとってパソコンは pull 型の、前のめりで集中力を要するメディアなので、あんまりこれで音楽や映像を楽しもうって気にはならないのよね。うまく切り替えができんのです。切り替えるならハードウェアごと切り替わってくれた方がいい。まぁ PodCast されたデータを自宅サーバで管理しておいてテレビやオーディオから出すっつーんなら、それはアリかなぁという気はするけど。まぁだから iPod で聴くっつーのはとても理にかなっているんだけど、都会の人間と違ってそんなに通勤時間長くないし、電車じゃないからじっくり機械を操作できる状態じゃないしねぇ。

風邪気味

疲労ですかね。関節痛まで出てきました。関節痛という言い方が一般的なのでそう言ってますけど、実際にはなんか

  • ホネがバキバキ言う
  • 頭痛がする
    • 肩凝りがものすごくひどくなった感じ

て感じで、関節痛と一言で言ってしまうにはちょっと違和感があるけど。とりあえず痛みは放置して鼻水の方を鼻炎の薬で止める。昨日もこれ飲んでかなりボーっとしていたので今日もちょっと心配だけど、仕方ないか。中途半端な状態は中途半端な状態でつらい。

About

例によって個人のなんちゃらです