PHPの配列の参照渡し

また一つつまづいたところを書きます。PHPの配列を関数に渡すと、デフォルトでは参照渡しではなく、なんと値渡しになってしまう。

<?php
$array = array('i', 'have', 'black', 'hair');
SetHage($array);
print_r($array); //Array ( [0] => i [1] => have [2] => black [3] => hair )
function SetHage($array)
{
$array[2] = 'no';
}
?>

ハゲにならない。SetHage関数には、$arrayの内容がまるまるコピーされて、$array[2]を変更しても元の関数に何の影響も与えてない。PHPで配列とはリテラルそのもの、ということなのか?これもC言語使いやJavaScriptからしても不思議な挙動で、ふつう配列はポインタが関数に渡されるものだ、という感覚でコードを書いてしまう。マニュアルによれば、配列の内容を書き換えたかったら明示的に参照渡しを使え、ということだそうだ。でかい配列をたくさん作ったのなら、それを使う関数は参照渡しにしておかないとオーバーヘッドかかってしょうがないことになりそうだ。

<?php
$array = array('i', 'have', 'black', 'hair');
SetHage($array);
print_r($array); //Array ( [0] => i [1] => have [2] => no [3] => hair )
function SetHage(&$array)
{
$array[2] = 'no';
}
?>

これでめでたくハゲになりました。


PHPの配列

PHPの配列はハッシュだけでできているので、ふつーの数値インデックスの配列と違って、要素の削除が面倒だ。unsetで要素を削除すると、歯抜けの配列になってしまう。

<?php
//0 =>"foo", 1 =>"bar", 2 =>"hello", 3 =>"world"
$array = array("foo", "bar", "hello", "world");
unset($array[1]); ///1番目の要素"bar"を消す
var_dump($array);
?>

array (size=3)
0 => string 'foo' (length=3)
2 => string 'hello' (length=5)
3 => string 'world' (length=5)

番号0,2,3の歯抜け配列になってしまった。これをforループすれば、当然エラーになる。私のようなC++のvector, C#のListばっかり使っている人間には直感的にすぐに理解できないが、C#のDictionaryと挙動は同じだ。でも、数値が連続していることが前提でないと、プログラムを組みずらい。
いろいろ調べてみると、array_spliceを使えばいいらしい。

<?php
$array = array("foo", "bar", "hello", "world");
array_splice($array, 1, 1);//1番の要素から1つ分、つまり"bar"を消す
var_dump($array);
?>

array (size=3)
0 => string 'foo' (length=3)
1 => string 'hello' (length=5)
2 => string 'world' (length=5)

面倒じゃのう。何でもハッシュだと思ってやった方が楽かもしれないね。


DB構造再編

旧TrainNaviでは路線や駅に番号を振っていたが、これは拡張性を妨げるので、やめる。例えば、数年後に山手線新駅が完成する。このとき、駅を挿入するためには駅番号をずらさなければいけない。するとあちこちのDBも同時に直さねばいかず、必ず漏れが出てデバッグが大変になる。
路線番号はもっと拘束が大きい。簡単にインポート・エクスポートなどを行うためには、邪魔でしかない。インポート時に手元のものと衝突するから路線番号を変えなければいけない、なんてことになるとすごく手間だ。
路線番号や駅番号は廃止しよう!路線名や駅名で直接selectするのでよし。PHPもJavaScriptにも連想配列があるから、むしろ文字列の方が楽だ。
今回は正確な緯度経度を基にして駅を配置するから、駅と駅の間を直線で結ぶだけでは、特に駅間距離が長いときに不恰好になってしまう。それに、常磐線と常磐快速線のように停車駅が異なるとき、経由する線路が同じなのに描画すると線路がずれる、なんてダサいことも起こりうる。なので、駅と駅の間に、任意に経由地を挿入できるようにするべきだ。そうすれば、キレイな路線が書ける。いっそのこと曲線も書けるようにした方がいいかもしれない。電車のオブジェクトを動かすのが大変だけれど。
と色々と想像は膨らむけれどこれを全部実装するのは相当な手間だな。

暫定のDB構造

  • tnline 路線テーブル
    • linename 路線名
    • linecolor 路線の色
  • tnstation 駅テーブル
    • linename 路線名
    • stationname 駅名(空欄にすると経由地を表す)
    • kilo 営業キロ
    • latitude 緯度
    • longitude 経度
  • tntrain 列車テーブル
    • linename 路線名
    • trainname 列車名(列車番号)
    • service 平日か土日か
    • trainkind 列車種類(急行とか各停とか)
    • nextlinename 直通先路線名
    • nexttrainname 直通先列車名
  • tnroute 経路テーブル
    • linename 路線名
    • trainname 列車名
    • service 平日か土日か
    • startstation 発駅
    • endstation 着駅
    • starttime 発車時間
    • endtime 到着時間

Artur Rubinstein(piano), Symphony of the Air(orch), Alfred Wallenstein(cond) – Saint-Saëns: Concerto No. 2 / Franck: Symphonic Variations / Liszt: Concerto No. 1(RCA Living Stereo CD56)


★★★☆☆
ポーランド出身のユダヤ人、アルトゥール・ルービンシュタインのピアノ協奏曲が3曲も入っているこのアルバム、やや録音が古く、しかも後半の2曲は恒例のオケの音ずれが頻発します。アメリカの楽団は元気はいいんだけど荒っぽい。。20世紀に活躍した大演奏家はみんなユダヤ人だ。なんで?
フランス音楽といえばいわゆるエスプリに富んだ、一歩引いて訳分かるような分からないような謎和音を繰り出しまくるのが特徴ですが、サンサーンスのピアノ協奏曲第2番はこの法則に当てはまらず直球です。特に第一楽章。マイナーでドジャーンと攻めるド演歌とベートーヴェンを混ぜたような波がやってくる。ピアノ爆速の第三楽章も聞きごたえがあります。
ダサカッコいい系譜の強肩打者、リスト様の協奏曲は冒頭の旋律がいつも通りの激ダサで、胸に響きます。終盤に再び現れるメインテーマも安定のダサさ。これを強烈に荘厳に演奏してくれるといいのだけれどピアノ以外はいまいち。木管が浮いてるし全体的にずれてる。ピアノは見事です。明らかに規格外のキチガイ譜面なのに超絶かっこいいです。オケがもうちょっと上手だったらなあ、残念。他のCDでもう一度聞いてみたい。


おととい見た夢

大きなホールでマイクを仕掛けてコンサートの様子を録っている。アーティストはなぜかゴールデンボンバーのようなビジュアル系だ。私はMCに付き合わされたり、歌わせられたりしている。
私が舞台を離れると演奏が始まる。私は誰かを探しに行く。一緒に演奏を聴きに来た誰かを。誰なのかはわからない。途中に母がいる。「よくこの会場まで来れたねぇ」と言われる。私は急いでいるので無視して会場を出る。マイクのことが気になる。ホールを出て図書館を抜け、地下階まで移動した後、母の言動にむかっ腹が立ったので一度ぶん殴ろうと、またホールを目指す。しかしなかなか到着できない。どれだけ歩いてもデパートの商品売り場だ。演奏が聞こえてくるが、何故かオーケストラに変わっている。
やっとのことでホールに続く道標の看板を見つけて、ロビーに入ると演奏は終わってしまっていて、弦楽器を抱えた数人の集団が階段を下りてきていた。チェロを抱えて私と同じくらいの年の女性が手招きで挨拶する。私はそれが誰か分からないのだが分かったふりをして挨拶するも、数秒でいたたまれなくなり「誰だっけ?」と言うとその女性は謎のポーズとセリフを発するのだが私はそれで何故か演劇部のAさんと分かる。「チェロは前からやってたのよ」と言って去っていく。
私は客席に行くも結局誰も見つからない。ここで目が覚める。


TrainNaviリファクタリング準備

LanguageTrainerがある程度完成したので、次はTrainNaviをもっと実用的なものにしたい。具体的にやらなければいけないことは次の通り(優先度順)。

  • 時刻表・列車データの充実
    • いま小田急・京王・JR中央線しかないのでさらに追加、できれば首都圏全域まで拡大したい
    • そのためには、入力の手間(すっごい面倒)のスクリプト化による大幅な省力化が必要
    • データベース形式も見直すべき
  • 画面刷新
    • 位置情報を駅に付加して地図のような画面表示をする(いまは縦一列にしか並んでいない)
    • 総武線+中央線や京王線+京王新線など、複数路線並列の場合の対処が必要
  • 描画処理の高速化
    • 特定の路線、特定の列車種類だけの表示
  • 時刻表データのファイル出力、入力
  • ターゲット列車、もしくは経路を指定して強調表示
  • 駅をクリックしたら時刻表を表示

画面表示についてはかなり大幅なリファクタリングが必要になりそうだ。初めてだからしょうがないが、ビューをもっと厳格に分離して簡単に首を挿げ替えられるようにしておくべきだった。
描画処理の高速化については、駅や路線については一切再描画が必要ないので、こいつらに対してobject.cacheを使えば相当の高速化が見込まれる。列車本体もほとんど再描画しないのでこいつにも適用するべきだ。


Steven Wilson – The Raven That Refused To Sing (2013)


★★★★★
21世紀のプログレを聞いてみたい、と思い、事前知識何もなしで、こちらのTop 2013 albumsの1位のアルバムを試しに聞いてみた。
これは。。良いです!UKロック、ジャズ、少々のクラシック、エフェクト、古いプログレ、ビートルズなどの良いところを全部持ってきながら、芯の部分はスタンダードなUKロックを貫き通している、という、現代ならではの楽曲たちだった。6曲すべてに相当気合が入っているのがわかる。ヴォーカルも若さで飛ばしている。さすが21世紀だけあって、録音技術、マスタリングは完璧だ。そして、本当にたまたまなんだけど、キングクリムゾンがいつも使っていたメロトロンの音が!驚いた。
Steven Wilsonについて調べてみると、若さで飛ばしていたと思っていたのに、46歳だった。でも顔はめちゃ若い。なぜあんな澄んだ声が出せるのか。。そしてやはりというべきかイギリス出身のプロデューサー兼ミュージシャン。クリムゾンの魂を受け継ぐ者ということか。
日本人、特にファミコン・スーファミ世代にプログレは親しみ深い。ゲームミュージックでよく使われる曲調だから、だ。おそらくこの時代のゲーム作曲者がみなプログレファンだったんだろうな。特に3曲目The Holy Drinkerなんか、クロノトリガーやFF6をやりこんだ人にはグッとくるのではないか。
そして特筆すべきはドラムスだ。Marco Minnemann という人らしい。異常に上手い。普通のリズムを叩いているかと思うと時々あり得ないようなリフを繰り出す。力をためておいて攻撃力2倍という感じだ。この人も要チェックだな。
ジオンはあと10年は戦えると言いつつ2か月で敗北してしまったけれど、プログレはまだまだ戦えそうだ。ポップな要素も取り入れつつ次のステージに向かうのでしょう。


compromise

PHPの本を読んでいて、unlinkを利用したファイルの削除のところで、どうもわからない単語に出会った。

Whenever you access files on your hard disk directly, you must also always ensure that it is impossible for your filesystem to be compromised.
For example, if you are deleting a file based on user input, you must make absolutely certain that it is a file that can be safely deleted and that the user is allowed to delete it.
(Learning PHP, MySQL, JavaScript, and CSS, 2nd Edition P144)

このcompromiseというのは通常「妥協する」という意味なのだが、妥協では文脈と会わないし、受動態なので「妥協される」となりさらに意味不明だ。ファイルシステムを安全に保てよ、壊されないように気を付けろよ、と言っているように見えるのだが、辞書に載ってない。
web検索してみると次のようなページが見つかった。

辞書に見る”compromise”はリスクの概念に留まると思われるのですが、昨今のセキュリティ関連のニュースで用いられる”compromise”にはもっと具体的な意味、つまり不正利用、暴露、犯罪目的の利用、などが含意されているように思われます。

Merriam Websterでは、
to reveal or expose to an unauthorized person and especially to an enemy
という定義(と<>内は例文)が見られます。このような定義はAmerican Heritage Dictionaryや英和辞典に見られず、昨今のセキュリティ関連のコンテクストでの用法を他に先駆けて取り入れたものではないかと思われます。

なるほど!じゃあやはり、「ファイルシステムが危なくならないように気を付けろ(壊れないように気を付けろ?)」と言ってるので間違いなさそうだ。こんな風な単語の術後的な使い方は、専門的になるほど増えてくるのかなぁ。日本語ですら面倒なのに憂鬱だなぁ。


HSK1-3級

HSK Word Listsをエクセルに取り込み、順にチェックして知らない単語の辞書を引き例文付きで網羅的に覚えていく実験中。1〜3級までようやくチェックが終わり、たった600語のうちなんと42語も知らない・理解の怪しい単語があった。まずすぎる。5,6級はもう全然知らないんじゃないか。6級5000語への道は遠い。


HTML5でグラフ

canvasを使ってグラフを描きたい。用途は、LanguageTrainerの統計機能。ペース配分に使いたい。
flotr2というライブラリを使うとラクラクグラフが書けるらしい。サンプルコードはこちら
PHPとJavaScriptを連携させるしかないが、グラフの数なども動的に変える必要があるので、次のように実装する予定。
・PHPでMySQLを使ってDB読み込みし、必要な情報をjson形式で変数に保存しておく。さらに、グラフ表示用のHTMLタグもPHPで生成する。
・JavaScript側ではグラフの描画だけを担当する。PHPで作った情報を使ってグラフ表示する。
今日は構想だけで時間が来てしまったので、ここまで。