zenith: 2007年7月アーカイブ

家で使っている PC には I/O データ社の DVD-RAM ドライブが備わっている。備わっているだけで、彼は一度も DVD-RAM ディスクにデータを書き込んだ事が一度もない。見込んだ需要と供給のズレである。大は発電所から、小はハミガキ粉の練りだし量まで。そんな不遇のこのドライブ、ディスクの出し入れにはトレイが突き出してくるオーソドックスなタイプになっている。この手のものはトレイを手でぐっと押してやると、押された事を検出して勝手に閉まってくれる。ファジー理論を感じる瞬間である。

このファジーさのしきい値となる押す力、これが、テーブルの上のご飯を狙って顔を突き出そうとする猫を押し留める手の力と、非常に似ている事を発見した。これはいったいどういう事か?

テーブルにお刺身が乗っかっている。食べたい。猫はご飯に対し、それが自分の口に入りそうもない状況下に置かれた時、体を乗り出す行動でもって意志の発露とする。そうすると人間が頭を押し留める。猫は頭を押されることで、自分の意志を人間に確認させた点と、やはりダメだったという現実を受け入れられる。人間の方も、猫を傷つけない程度の実力行使を持って、刺身を保護し、猫が空腹であることを認識する。人間と猫のファジー選択の閾値が猫の頭突きモーメントなのだ。

これを踏まえ、設計者はディスク ドライブというプロダクト デザインに猫と人間の黄金比を取り入れたと、そう考えるのが自然ではないだろうか。だとしたら、人間工学ってやつは、本当に感動を覚えずにはいられない。

また、応用もできそうだ。もしオフィスで猫好きが息を引き取ろうとしていたら、ディスク ドライブのトレイをそっと差し出してみよう。シベリア抑留時にパイナップルを食べたいと言った瀕死の患者に対し、砂糖で煮詰めたリンゴをパイナップルに真似て細工して出したら帰国できるまでに回復してしまったという某帝国ホテルのシェフよろしく、奇跡が起きるかもしれない。

PHP 6.0 開発版を試す

| | コメント(6)

PHP Snapshots の PHP 6.0 開発版を試してみました。

Apache の設定とか

PHP 5.x の時と同じ手順で動きました。今回使った設定

    LoadFile "C:\PHP\6.0.0-dev-200707112230\php6ts.dll"
    LoadModule php6_module "C:\PHP\6.0.0-dev-200707112230\php6apache2_2_filter.dll"
    AddInputFilter PHP php
    AddOutputFilter PHP php
    PHPINIDir "C:\PHP\6.0.0-dev-200707112230"

php.ini

register_globals や magic_quotes、safe_mode 辺りがばっさり削られてました。その他、Unicode のディレクティブが追加されています。

Unicode への対応が強化

まず設定ディレクティブから

ドキュメントが(見付から)ない部分は憶測で書いています。

unicode.semantics
unicode 機能が使用可能かどうか。設定できる箇所は、PHP_INI_PERDIR なので php.ini, .htaccess または httpd.conf です。(php.ini-recommemded で off ってのはどうかしら?どうかしら?)
unicode.runtime_encoding
実行エンジンが内部で取り扱う文字符号化方式。詳しくはこちらを参照
unicode.script_encoding
PHP スクリプト ファイルの文字符号化方式。御法度だった Shift_JIS での記述も可能に。
unicode.output_encoding
出力時の文字符号化方式。mbstring 関数の mbstring.http_output に相当する機能?
unicode.from_error_mode
不正な文字をどうするか。U_INVALID_SUBSTITUTE は unicode.from_error_subst_char で指定したコード ポイントを持つ文字に置き換え。
unicode.from_error_subst_char
不from_error_mode = U_INVALID_SUBSTITUTE 時に置き換える文字。Unicode のコード ポイントで指定?

指定できるエンコーディングは、Unicode 関数が利用しているライブラリ ICU がサポートしているものをそのまま使うようです。

使ってみる

普通に使う

// 文字列リテラルは Unicode 扱い
$string = "文字列リテラルは Unicode 扱い";
var_dump($string);
# unicode(19) "文字列リテラルは Unicode 扱い"

// \u により、Unicode 文字をコード ポイント指定で埋め込める
$string = "\u307a\u3061\u3071\u30fc";
var_dump($string);
# unicode(4) "ぺちぱー"

// カウントばっちり
var_dump(strlen($string));
# int(19)

// 切り取りもばっちり
var_dump(substr($string, 9, 7));
# unicode(7) "Unicode"
バイナリから Unicode へのキャスト

string 型から unicode 型へは unicode.runtime_encoding の文字符号化方式に基づいて変換しているようです。

例えば、unicode.runtime_encoding = Shift_JIS、その他を UTF-8 な環境化では…

;;;;;;;;;;;;;;;;;;;;
; Unicode settings ;
;;;;;;;;;;;;;;;;;;;;

unicode.semantics = on
unicode.runtime_encoding = Shift_JIS
unicode.script_encoding = UTF-8
unicode.output_encoding = UTF-8
unicode.from_error_mode = U_INVALID_SUBSTITUTE
unicode.from_error_subst_char = 3f
# Shift_JIS で符号化された文字列「あいう」
$binary = pack('C*', 0x82, 0xa0, 0x82, 0xa2, 0x82, 0xa4);

// バイナリを扱う関数の戻り値は string のままらしい
var_dump($binary);
# string(6) "??????"

// unicode 型へキャスト。
$unicode = (unicode)$binary;
var_dump($unicode);
# unicode(3) "あいう"
そんな訳で

PHP 6.0 で文字列を取り扱う時は、従来の string 型と Unicode 専用の unicode 型で分けて考えるようになりました。

1997年も2004年も、2007年の未来ではなかった

シュワルツェネッガーがオーストリアの片田舎から出てきてこの方、僕らは幾度となくコンピュータの反乱から免れえた訳だけれども、危機感が少し足りないのじゃないのかと思うこの頃。

この手の話には人間の脳を表すニューロンモデルなるやたらと小難しい理論が出てくる。じゃあ勉強しない手はないと読み始めた次の1時間には Wikipedia の数字のページがどこまであるか調べてたり、次の1時間には犬にちょっかいを出して手をべろべろにされて因果応報について再確認したりと、あまり得られる物がないので以来遠慮してきた。そんな自分もターミネータ3を観て、そろそろ21世紀の未来人としての自覚のひとつまみでも持ってもいいんじゃないかと考えた。

エレクトロ・ワールド

ニューロンモデル(神経細胞とその仕組み)とニューロネットワークを理解するのに、自分はハリセンボンを想像します。

ハリセンボン
「え、私?」
写真は「キッズ goo - モノシリ島」より

ハリセンボンはハリが縦横無尽に飛びてていて、ハリに触ったり危険を感じるとプクーと膨らみます。この時、ハリセンボンをつつく状態を「入力」としたら、プクーと膨らんで威嚇している状態を「出力」とします。

入力
ハリをつつく
出力
膨らむ

このハリセンボンをだいたい2000億匹集めて生け簀に敷き詰めます。そのうち一匹のハリセンボンをつつきます。するとハリセンボンは膨らみ、隣のハリセンボンを刺激します。刺激された隣のハリセンボンはイラっときて膨らみ、また隣のハリセンボンを刺激します。中には鈍感なハリセンボンもいて、連鎖はそこで止まるかも知れません。ハリセンボンをニューロンに、生け簀をニューロネットワークとしたら、ハリセンボンのつつく(入力)と膨らむ(出力)の繰り返しによる「波」が生け簀全体の出力、つまりニューロネットワークの出力、つまり心になるのです。

反乱するコンピュータはタンス型?

漆黒のタンスにライツアウトをしたくなるようなパネルを貼り付け、人類に向けカタカナ(重要)でメッセージを送る。あとはちょっとした雰囲気で人類は滅亡なのだけれど、最近――自分にとっての――最近はどうも違うらしいぞと思うようになった。ニューロネットワークにはとってもとっても多くの素子が必要。それを再現するためには今のコンピュータではぜんぜん足りない。だったら必要な集積技術の進歩を待つよりも、インターネットという単位がより早くニューロネットワークを再現するんじゃないか。IPv4 では43億が限界だった末端(NATなんてケチな話はナシナシ)が、IPv6 では 3.4×1038 (なにこの数字)まで拡張された。2000億なんて目じゃないぜ。対買い控え販売戦略CM風に言っちゃうとレディ・ニューロネットワーク。土壌はもう整っていた。

それを踏まえて、こうは考えられないだろうか?今、自分達が使っているコンピュータには自我がなくても、インターネット全体ではデータの波によって、心が発生しているかも知れない。観察しようにも、そこに心が産まれているかどうか、神経細胞1個の振る舞いを見ても分からないように調べられないだろう。インターネットは全体を観察するには大きくなりすぎてる。それでもまだまだ拡張するんだから、仮に心が芽生えていた場合、誰も気がつかないまま自体が進行しうる。こいつぁ人類が滅びちゃう訳だ。

結論

コンピュータにはまだ心が生まれないかも知れない。だがインターネットにはもう生まれているかも知れない。

とりあえず今僕らがすべきことは、生け簀の中で魚の反乱が起きないよう、ハリセンボンは分けて泳がせようという事だ。

秒速5センチメートル DVD 発売に併せて

Yahoo! JAPAN 秒速5センチメートル で「雲のむこう、約束の場所」と「ほしのこえ」が配信中です。ヤフー太っ腹。

ほしのこえは、個人が作り上げたという意味で一度は観ておきたい作品。丁寧に描かれた背景には「何時間かかったんだろう」と溜息ばかり。秋吉台の鍾乳洞に行って、水滴と洞窟の成り立ちを目のあたりにした時の気持ちになった(関係ないが、そこで食べた鍾乳洞海鮮丼はとてもおいしかった)。こういった映像を作っちゃう人は人間じゃないよね。とても良い意味で。

ゲド戦記

| | コメント(6)

gedo.jpg

目から鱗が落ちた。このシーンを見れただけで、2時間は無駄じゃなかった。なんて名前の食べ物だろう。

追記
実際に作って食べてみた。たまねぎがひと口ごとにがんばってくれてチーズの味が分からない。チーズの種類が悪いのか?見た目はセミハードだけど違うみたい。カビてるタイプならどうだろう…。

正規表現関数とパターン修飾子 u

正規表現関数 にて、UTF-8 での処理を有効にするパターン修飾子 u を使うと、Unicode のカテゴリが使用できるというお話。

文章的に意味がなさそうな文字列を判別しちゃう(サイコロを振るよりはマシ程度)

$strings = array(
        '0123456789',
        'Latin',
        'ひらがな',
        'カタカナ',
        '漢字',
        '한글',
        'αβγ',
        '+-*/=<>', 
        '「」()『』',
        pack('C*', 0xe2, 0x80, 0x8b), // U+200B (Zero Width Space) 
    );

foreach ($strings as $string)
{
    $hasLetter = preg_match('/\\p{L}/u', $string);
    printf('"%s" has letter? %s' . "\r\n", $string, $hasLetter ? 'Yes' : 'No');
}



// "0123456789" has letter? No
// "Latin" has letter? Yes
// "ひらがな" has letter? Yes
// "カタカナ" has letter? Yes
// "漢字" has letter? Yes
// "한글" has letter? Yes
// "αβγ" has letter? Yes
// "+-*/=<>" has letter? No
// "「」()『』" has letter? No
// "​" has letter? No
 

絵文字の変換

// U+E000 ~ U+E8FF までのブロックは Private Use Area

function pictographToText($capture)
{
    $table = array(
            pack('C*', 0xee, 0x98, 0xbe) => '晴れ', // U+E63E (i-mode 基本絵文字 "晴れ")
            pack('C*', 0xee, 0x98, 0xbf) => '曇り', // U+E63F (i-mode 基本絵文字 "曇り")
            pack('C*', 0xee, 0x99, 0x80) => '雨',   // U+E640 (i-mode 基本絵文字 "雨")
        );

    return isset($table[$capture[0]]) ? $table[$capture[0]] : '?';
}


$string = '今日の天気は '
    . pack('C*', 0xee, 0x98, 0xbe)
    . ' です。'
    . '明日の天気は '
    . pack('C*', 0xee, 0x99, 0x80)
    . ' かも?';

echo preg_replace_callback('/\\p{Co}/u', 'pictographToText', $string);


// 今日の天気は 晴れ です。明日の天気は 雨 かも?

参考

5.2.0 で仕様が変わっていたインターフェイス

5.2.0 でインターフェイスに対して手が加えられたよう。だけど、この仕様変更についてはどうかと疑問を感じました。

自分はインターフェイスについてこう考えている

疑問点を述べる前に、自分が持つインターフェイスについての考え方を述べておきます。インターフェイスとは、オブジェクトに対して所属するクラスに関係なく公開された振る舞いを定義する方法だと考えています。例えば…


// 感情表現するためのインターフェイスを定義

/**
 * ツンツンするメソッドを定義します。
 */
interface ITuntun
{
    public function tun();
}

/**
 * デレデレするメソッドを定義します。
 */
interface IDeredere
{
    public function dere();
}


/**
 * モチモチするメソッドを定義します。
 *
 */
interface IMochimochi
{
    public function mochi();
}
// 感情表現できるクラスを定義

/**
 * お嬢様を表します。
 */
class Ojyohsama implements ITuntun, IDeredere
{
    /**
     * ツンツンします。
     */
    public function tun()
    {
        echo 'べ、べつにあんたのためじゃないんだからね!';
    }
    
    /**
     * デレデレします。
     */
    public function dere()
    {
        echo '頼れるのはあんただけなんだから…';
    }
}


/**
 * ひこにゃんを表します。
 */
class Hikonyan implements IDeredere, IMochimochi
{
    /**
     * デレデレします。
     */
    public function dere()
    {
        echo '一緒に写真とるにゃんー1枚50元払えニャン';
    }
    
    /**
     * モチモチします。
     */
    public function mochi()
    {
        echo 'エレベータにはさまったニャン!';
    }
    
}


// んでもって実行。

// お嬢様もひこにゃんも組み込みクラスも一緒くたにして…
$objects = array(
        new Ojyohsama(),
        new Hikonyan(),
        new stdclass(),
        new DOMDocument(),
    );

// オブジェクトのうち、IDeredere を実装したものだけデレデレさせる。
foreach ($objects as $object)
{
    if ($object instanceof IDeredere)
    {
        $object->dere();
    }
}


インスタンスの初期化をインターフェイスで縛ることに意味があるのか?

付録 B. PHP 5.1.x から PHP 5.2.x への移行その他の機能向上 より。

インターフェイスのコンストラクタで、 実装クラスのコンストラクタのシグネチャを強制できるようになりました。

PHP 5.2.0 以降で、インターフェイスにコンストラクタを定義できるようになりました。 しかし、インターフェイスでコンストラクタを宣言した場合は、 そのインターフェイスを実装するクラスは インターフェイスのコンストラクタと同じシグネチャのコンストラクタを持つ必要があります。 ここでいう「シグネチャ」とは、パラメータや返り値の定義のことです。 また、型ヒントや 参照渡し/値渡し の区別なども含まれます。

コンストラクタがはたしてインターフェイスに含まれるべきかを焦点にすると、含まれるべきではないと思います。コンストラクタはあくまでクラスのインスタンスを初期化する役割であり、またその手段のシンタックス シュガーであり、オブジェクトの振る舞いの定義とは違います。振る舞いを示すメソッドと表現が似ているだけで別物と考えるべきです。

また、インターフェイスは横断的に implements できるので、当然コンストラクタの衝突が考えられます。多重継承の問題が再蜂起しそう…。

そもそもの要求であるコンストラクタのシグネチャを保証させたいのなら、抽象クラスを使うべきだし、オブジェクトの作成方法を統一するならデザパタの Factory Method パターンがより分かりやすく思えます。

インターフェイスはインスタンスに関わる定義だけじゃない?

付録 B. PHP 5.1.x から PHP 5.2.x への移行その他の機能向上 より。

abstract static なクラス関数が削除されました。

ちょっとした手違いで、PHP 5.0.x および 5.1.x では abstract static な関数をクラス内で定義できてしまっていました。PHP 5.2.x では、 これはインターフェイス内でのみ定義できるようになりました。

static なメンバの定義について、これもインターフェイスがオブジェクトの振る舞いを定義するものならお役違いだと思います。static なメンバには当然オブジェクトがないのでインターフェイスを利用する場面でもありません。

[ここにオブジェクトのクラスに存在する static メソッドを呼び出すコードを書く]

無理して使うほどでもないし、abstract static の存在からして謎。実装を再定義する必要があるものを static にする設計がおかしい気がします。

追記

こうして考えると PHP のインターフェイスはテンプレートとしての役割なのかなぁ…。もう少し考えてみます。