sci

最果て風呂

mto を PHP で実装してみる

OSX には PHP が標準で装備されていることを知り実装してみた。スクリプトの実行だけならば Node.js のような感覚で使うことができるようだ。とりあえず Rubyスクリプトを参考にしながら PHPスクリプトを書いてみた。

環境変数の取得

まずは辞書の場所を得る。環境変数の取得には getenv("") を使う。文字列の連結には . が使え、Vim script や Lua っぽい感じがする。変数に $ が付くのは Perl っぽくて鬱。

ファイルの読み込み

ファイルの読み込みは fopen() を使う。これを while の中で fgets() に渡して一行ずつ読み込んで処理する。最後に fclose() で閉じないといけないのが面倒ではある。この辺は C っぽい。

正規表現

正規表現系の関数には preg_ が付いているみたい。preg_match() で検索語が含まれているかどうかを確認し、preg_replace() で置換する。preg_split()Ruby.split() みたいなことができる。どれも手軽に使えて便利だ。

繰り返し

配列の要素を回すのに foreach() を使った。for ... in... に慣れていると、() が面倒に感じてしまう。as って何や。文字列の検索・置換には str_replace() を使う。関数名がわかりやすい。

引数処理

$argv に入っているので、if 文中で == で比較して分岐。多くの人は === を使っているようだが?

テスト

およそ 3 時間弱で形になったので test させてみると、旧字体から新字体に変換させる部分で NG になってしまった。調べてみると、作成した内部辞書がまずいようだった。下記のように文字化けしてしまっている。

隠滅 /湮? (正しくは「湮滅」)
叙情 /抒? (正しくは「抒情」)
里謡 /俚? (正しくは「俚謠」)
褐 /?     (正しくは「渴」)
悦 /?     (正しくは「悅」)
税 /?     (正しくは「稅」)

バイトの途中で切られてしまったみたいだね。正規表現の部分を /\s+;.*/ から /[ \t]+;.*/ に変更すると期待通りの内部辞書になりテストが OK となった。

ちなみに上記の漢字はテストの例文では使っておらず、旧字から新字へ変換する時にたまたまバイト列が合ってしまい、例文がおかしくなってエラーを検出できたという流れ。運が良かった(しかしこれ以外のテスト方法なんて思いつかないんだけどな)。

感想

日本語の情報が多く、知りたい事にすぐに辿りつけた(だからすいすい実装が進んでメモをちゃんと書いていない……)。PHP のドキュメントは頑張ってるなぁ。手軽だし、関数名がわかりやすいし、情報がたくさんあるしで、PHP が人気なのがわかる気がした。文中にも書いたけれど、C と PerlVim script に似ていると思った。

ただ、<?php?> がね。特にスクリプトとして使う場合は ?>つけてはいけない というのが混乱する。

ベンチマーク

恒例のベンチマークをしてみる。前回と同様、16KB のファイルを読み込ませて、新仮名から旧仮名に変換するというもの。意外と使えそう。

1
C 0.123
CC 0.106
Go 0.256
C#(mono) 0.165
node 0.107
Lua 1.176
Lua-JIT 0.891
Perl5 0.085
Python3 0.079
Ruby 0.149
mruby 0.869
PHP 0.408

f:id:nakinor:20160323202050j:plain