宣伝に偽りありで申し訳ございません -- CodeIgniter自体は急激に変わっていない

http://d.hatena.ne.jp/tanakahisateru/20080924/1222190229
を受けて、
http://angelicwing.net/diary/5012.html
と思われたみたい。宣伝に偽りありで申し訳ありません。

えぇと、そうです、CodeIgniter自体が急激に良くなってるわけじゃないです。彼が主観的にいやになってきたのと同じように、私にとっては、彼が嫌になったと言ってるところについて、むしろ、主観的に良いと感じるようになってきたって意味でした。

まあね、私自身偉くもないのに、偉そうな人が言いそうなびっくり発言だもん、反感買ってもしょうがないか。

全体としてはエレガントじゃない、とくに、サブモジュール読み込みのメカニズムは激しくダサい($this->が面倒)けど、妥当なパフォーマンスと現実的な生産性の向上を得るためには、むしろ、(根が深い言語ランタイムの問題があることを承知のうえで)PHPを選んだんだからと覚悟を決め、(Perlハッカーのように)汚いのも受け入れて、さっさと仕事に向かおう、と思ったとき、自分の中でCodeIgniterが急浮上したというわけです。

  • 高負荷な美学を徹底排除し、速度を生のPHPと同等にした
  • PHPしか使えないようなレンサバ環境にすら持ち込める
  • PDOなしでデータベースAPIを汎化してあるので引越しが容易
  • PHPの使い方ベストプラクティス集にとどまってる

いやね、今日ソースを見てて、マニュアルでActiveRecordとかModelとか言ってる部分は、ホントにダサい、ていうか、Modelなんてただただコントローラ外の静的関数の置き場でしかない(Modelと言いつつ、DAOシングルトン)し、ActiveRecordは完全に誤解した名前(CIのActiveRecordは、RoRのActiveRecord実装からActiveRecordパターンを除去して残ったユーティリティ関数集)だし。ActiveRecordなのに、リレーションの解決に何の手助けもないという冷酷さときたら(w。

過剰なフィールドを持つオブジェクトや、自動トランザクションコミットなんて要らない。データベースは「表」だ、オブジェクトツリーなんぞと対応付けてるCPUコストなんて払えるか、というメッセージがありありと…。

まあでも、そういう、「普通の人が自作しそうなもの」で留まって、すごい技術をなにも与えてくれない厳しさが、CIの素敵なところなんだけどね。「うちは貧乏だからこれで我慢しなさい」って感じで。

----あ、すみません、調子乗って紛らわしい冗談こいてしまいました。

名前付けのセンスについて

非常に極端な例ですが、名前空間を分けるために関数/メソッド名をのばしてると、
某オープンソースのSNSみたいに50文字を超える関数名がやたらある、といった恐ろしい状態になりかねません。

メソッド名は不自然なほど長いわけじゃなく、なんだったら、array_key_existsより全然短い。(PythonRubyと比べて)PHP程度の文法だとホントに自然に構文になじむ名前付けって難しく、だったらまだ英文の語感的に自然なほうがいいかな、という新発想。

$this->session->userdata('hoge')も$this->config->item('hoge')も、単語だけ並べたら英語として一番しっくり来ると思うし、$this->load->plugin('hoge')も、プログラム言語としてはおかしな感じだけど、英文だと思えばなるほど。そもそもPHPがムリして不自然にOOPしようとしてるので、伝統的なOOPの常識に倣わないのもひとつの手なのかも。Rubyの名前センスの、もっと極端なの、という意味で。

セッションについて

> セッションをクッキーに直書きする

元記事の方で指摘しているのは
「serializeした変数をCookieに全部保存してるのはださくね?クライアントにはIDだけ持たせればいいじゃん」ということ。
対して言及している方の指摘は「ファイルシステムでセッションを持つのはださい」ということで、論点がずれています。
よく読みましょう。

あれ?「クライアントサイドセッションはおおむね万能」って言えば、おのずと「サーバサイドセッションじゃないとダサい」という発言に対応するものかと…。さらっと、「けしてダサいわけじゃない、デフォルトがクライアントサイドなのは、むしろモダンなほう。サーバサイドセッションが良いという発想は古い」と言ったつもりなんだけど。

で、明示的には言ってないけど、データベースに依存せず、かつ、セッションレプリケーションのためのネットワークもないとすると、もうファイルストレージかメモリしか選択肢がなくて、さらに、デフォルトでPHPはメモリを確保し続けることはできないわけで…。サーバサイドセッションのデフォルト保存場所は、ファイルしかないという大前提は、そんなに考えなくても出てくる答えだと思ってた。特に工夫をしないと、ファイルでセッションを持つしかないサーバサイドセッションはダサい。

なんとかするにはDB保存が一番近道で、でも、せっかくDBに保存するんなら、BLOBにして汎用用途にするんじゃなくて、ドメイン特化な仕組みを持ってもいいんじゃないの?でもそれには、きちんとしたクッキーの保存が保証されてないとね。あ、そのモデルを提示するために、CIはしきりにクライアントサイドセッションを主張してたのか、と思って、激しくナウいと思いました。個人的に。

第三者に解けない暗号なら、ネットワーク上を最大4KBのデータが行き来するのは、特に問題ないと思うし、サイズの問題はストレージを明示的に確保することで解決。どっかダサいとこあるかな?それでもクッキーが個人的に嫌か、政治的に通じないのなら、無理強いはしないけど、私はクライアントサイドのほうが好きです。

バリデータについて

正体不明なデータは「ユーザーからされる(意図している、してない関係なく)入力のすべて」でしょう。
そう考えた場合、validatorに$_POSTがハードコーディングされている状況は好ましくないのではないでしょうか。

私が間違っておりました - なんたらノート 第二期 を。

仰るとおり、たまたま、本当に$_POSTだけのチェックでいいかを検証してました。結論は、

  • $_POSTだけでなく、$_GETにも要る
  • セッションは安全
  • 通常のクッキー(Flashデータと勝手に増やしたクッキー)は要注意
  • でも、用途がUI用なのでまあいい
    そして、エラーメッセージを変数で取得するとデフォルトで
    〜
    に囲まれて来るという驚きのダサさを発揮してくれる。

「デフォルトがださい」という指摘に対して「変更できるよ」という指摘で、これも論点がずれています。

あ、そうか、囲まれること自体はいいってことか。すみません、ここは誤解です。Pタグがダサいなら、SPANかDIVだったらいいってことかな?

でも、「エラーの文章です」という意味で、Pが妥当じゃないとは言えないし、CSSで見た目SPANにもできるだろうし。

#my_field p {
  /* <td id="my_field"> 内のエラー */
  display:inline;
  margin:0px 0px 0px 1em;
}
<td id="my_field">
  <input type="..." value="<?php echo $this->validation->hoge;?>" />
  <?=$this->validation->hoge_error ?>
</td>

hoge_errorがPで囲まれてても、見た目でフィールドと同じ行に入るし、変なマージンもなくなるはずだけど。これ、囲みなしだとかなり面倒。

<td id="my_field">
  <input type="..." value="<?php echo $this->validation->hoge;?>" />
  <?php
    if($this->validation->hoge_error != '')
    {
  ?>
  <p><?=$this->validation->hoge_error ?></p>
  <?php } ?>
</td>

前のアレでわけわからないと仰ったぐらいだから、ここまで複雑なコードになると、「「エラーメッセージをどう見せるのか」はデザイン的な話で、View/Templateに近いところに書ける方が好ましい」かどうか、かなり疑わしいと思います。
「変数の値が存在すれば、指定したタグで囲んで表示するビューヘルパ」なんてのがあればいいのかも。でも、バリデータだけで完結して、その便利さを教授できるほうがお手軽なので良いとも思う。




さて、それじゃ最後に大長編を。見当違いも甚だしいとのことなので。

コード品質について

> PHPを最も上手く使う方法は、「汚かろうと何だろうと、とにかく正しく動けばいい」
> という妥協を積極的に受け入れることだと思う。

ここに対しては全く同意出来ません。
使い捨てでないコードがPHPで書かれることが多くなって今、わかりやすいコードを書くことは重要です。
下の方の言及で業務的な話も入れているのに、「汚くても動けばいい」などというのは見当違いも甚だしい。
あと、Smartyを使うことで綺麗なコードになるか、といわれれば違うしSmartyを使わなければ汚いコードになるか、というのも違います。

ということは、PHPに対して同意できないということになっちゃいます。

ここで自分が言いたかった「汚さ」は、書き散らした自分のコードのことではなく、PHPのことを指してたつもりでした。前の文脈の「コードの字面で選んでいいなら、そもそもPHP自体を避ける。」から続いて、「汚い」と書いてたので、まさかここで突然、自分のアプリケーション実装コードへと飛躍解釈されると思いもせず…。「ランタイムのAPI設計が汚かろうと…」と書けば良かったのかなぁ。

PHPはこれまでの経緯から、設計も実装も汚いことこの上ないソフトウェアだけど、その上に作られたソフトウェアがあまりにも多いので、それ自体を綺麗にすることを諦め、むしろ世界のPHPコードが今後変わらず動くことを第一義とし、下位互換をすべて保持したまま拡張しているソフトウェアなんだ、と思います。わかりにくい(というか、わかればわかるほど本質的に問題を抱えているとわかる)ランタイムを業務で使わないことは、とても重要。でも、採用不採用の天秤のもう一方には、特定の開発スケール(CGIより速く動き、ページが豪華で、デプロイ時の環境構成が保証でき、でも、アプリケーションサーバほど運用コストをかけても実行パフォーマンスが報われず、かつ、分散開発のプロセスよりも個人のハック能力が有利にはたらく案件)ではデファクトスタンダードかつオンリーワンだという現実もあり…。この、悪貨が良貨を駆逐しちゃった矛盾する現実に妥協できないと、ちゃんとしたプログラマーであればあるほど、PHPを割り切って使うことができない、って、ここまで言えば誤解はないと思うんですが、いかがでしょう?

Smartyを使うこととコードの質の関係は、あまり問題視していません。字面の好き嫌いよりも、実運用上の都合のほうが優先度が高いと、ただそれだけのこと。ただし、政治的な理由で天秤の傾きが不自然なことになる場合もあるので、パフォーマンスに問題がなければ、Smartyを採用するデメリットも、アーキテクチャ交渉のトレードオフとして解釈できるかな、と思います。いまや、クリーンな設計をイチからできる仕事のほうが少ないんだし。

ちなみに、表示系にSmartyを使ってMVCするのがお勧めだと仰っていたのは、たしか、Zendさんだったような。PHPは表示制御マクロじゃない、ビジネスロジックのための言語だ、と言いたかったのかな。でもどう考えても、PHPサーブレットよりJSPに近いと思うんだけどな。JSPビジネスロジックを書き、Velocityでプレゼンテーションせよ、ってこと?と言えば、私が、Smarty採用のトレードオフをコードの質とパフォーマンスで考えている人じゃないってことが、理解してもらえるだろうか…?

ううむ、またえらそうだ。

また火事になりそうな余談

わかりやすいプログラムを書くことが大事、なのはわかるんだけど、何が「わかりやすい」なのかを定義するのは本当に難しい。ただ、明らかに生産性が違うことが計測できれば、良いのは間違いない。逆に、汚いと感じても生産性に影響しない要素はどうなんだろう?だったら、何をもって汚いと言うのかも難しいと思う。

これは私の勝手な想像なんだけど、能力的に標準的なプログラマーにとっては、生産性を落とすほどプログラムを汚くするほうが困難なんじゃないだろうかと思ってる。書き続けにくいソースコードDRY原則の欠如したコード、相似性と対象性を欠いたインターフェース仕様、意味と対応しない名前付け、パターン化できない概念モデル群)では、彼がプログラムを完成させられないから。コードの質は完成のための当然の道具って感覚。

で、むしろ、人口比率で平均的なプログラマー(SE"さん"と呼ばれる、上級職のくせにPGよりスキルレスな人々も、かな)たちは、完成(長期的なバグフィクスのフェーズを含む)のための道具としてコードの質が十分条件を満たすかどうか以前に、しきりにコーディングの方法論を取り寄せては、過剰に武装しようとする(あー、差別用語でいうとデザパタ厨とか)傾向があるように思う。状況をわきまえず、いつも、「こりゃひどい、クリーンなコードを起こしなおさなきゃ」って言ってるだけの、ね。単に若くて勉強熱心な人々だってだけだといいんだけど、それとは何か違う臭いのする集合を感じることがあるのですが…ま、ほんとに目の当たりにしてるわけじゃないし、ただの気のせいなのかな。