Displaying posts written in

1月 2009

GeSHiのErlangプラグインでセミコロンを正しく扱う

Kreisquadratur» Blog Archive » Erlang syntax highlighting for GeSHi

こちらで配布されているErlangプラグインを利用するとセミコロンが <SEMI> に変換されてしまう、という問題について。先日は変数名のハイライトを諦めることでお茶を濁したが、やっぱりこれはGeSHiの仕様が悪いだろう、と思ったのでgeshi.phpを次のように修正した。

(’<SEMI>’ を “\x8″ に全置換しただけ。下のパッチはバージョン1.0.8の場合)

@@ -1942,7 +1942,7 @@
 
             //This fix is related to SF#1923020, but has to be applied regardless of
             //actually highlighting symbols.
-            $result = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $result);
+            $result = str_replace(array("\x8", '<PIPE>'), array(';', '|'), $result);
 
             // Timing is irrelevant
             $this->set_time($start_time, $start_time);
@@ -2774,7 +2774,7 @@
         //This fix is related to SF#1923020, but has to be applied regardless of
         //actually highlighting symbols.
         /** NOTE: memorypeak #3 */
-        $endresult = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $endresult);
+        $endresult = str_replace(array("\x8", '<PIPE>'), array(';', '|'), $endresult);
 
 //        // Parse the last stuff (redundant?)
 //        $result .= $this->parse_non_string_part($stuff_to_parse);
@@ -3952,7 +3952,7 @@
             //Circumvent a bug with symbol highlighting
             //This is required as ; would produce undesirable side-effects if it
             //was not to be processed as an entity.
-            ';' => '<SEMI>', // Force ; to be processed as entity
+            ';' => "\x8", // Force ; to be processed as entity
             '|' => '<PIPE>' // Force | to be processed as entity
             );                      // ENT_COMPAT set

コードの中にバイナリの 0×08 = 制御文字のバックスペースが含まれることはまずないので、問題にはならないはず。少なくとも <SEMI>よりはマシなはず。

これでErlangモードがきちんと動くようになった。

fac(0) -> 1;
fac(N) -> N * fac(N-1).

死んだはずのプロセスからメッセージが届く

『プログラミングErlang』8章に載っている on_exit/2 を使うと、既に死んでいるプロセスから死亡通知メッセージが届く、ように見える。

1> Foo = fun() -> 1 end.
#Fun<erl_eval.20.67289768>
2> Pid = spawn(Foo).
<0.33.0>
3> erlang:is_process_alive(Pid).
false
4> lib_misc:on_exit(Pid, fun(Why) -> io:format("~p dead with:~p~n", [Pid, Why]) end).
<0.33.0> dead with:noproc
<0.36.0>

これは erlang:link/1 の性質によるもの。man erlang より引用。

* If the calling process is not trapping exits, and checking Pid is cheap — that is, if Pid is local — link/1
fails with reason noproc.

* Otherwise, if the calling process is trapping exits, and/or Pid is remote, link/1 returns true, but an exit sig-
nal with reason noproc is sent to the calling process.

link/1の呼び出し自体は成功する、すなわち正常にリンクが確立できたように見える、というところがポイント。

この性質のせいで 9.8 の「キープアライブプロセス」の説明がおかしなことになっている。理解するのに丸一日かかったよ……。

『プログラミングErlang』8章 練習問題(2)

昨日貼り付けたコードにはバグがあったので、公開後に一度修正した(loop/3)。その時にリングを構築するための別の方法も思いついたので、下に示しておく。一度にまとめてプロセスを作るのではなく、子が孫を生む方式。

construct(N) when N > 0 ->
    spawn(?MODULE, prepare, [N]).
 
prepare(1) ->
    lib_ring:entryloop(self());
prepare(N) ->
    Next = spawn(?MODULE, prepare, [self(), self(), N-1]),
    lib_ring:entryloop(Next).
 
prepare(First, Prev, 1) ->
    lib_ring:loop(Prev, First);
prepare(First, Prev, N) ->
    Next = spawn(?MODULE, prepare, [First, self(), N-1]),
    lib_ring:loop(Prev, Next).

これで実行時間はさらに短縮された。プロセス数が多くなるほど差が顕著になる。

辞書方式:

N=100000, M=100
time=8.65, (9.113) seconds
N=200000, M=10
time=6.41, (7.012) seconds

子孫方式:

N=100000, M=100
time=7.05, (7.573) seconds
N=200000, M=10
time=1.67, (2.005) seconds

『プログラミングErlang』8章 練習問題

8.11の練習問題。これ本の中には答え載ってないのかな…?

自分なりの回答。時間計測部分のコードは省略。

  • コードの簡潔さを優先してリングの”始点”は固定にした
  • リストを配列代わりに使っているので効率が悪い

(続きを読む…)

Erlangを書くための準備

今さらながらErlangのための環境整備。

Emacsのerlang-mode追加
Emacs用のerlang-modeはErlangの配布物に含まれている。Mac Portsでインストールした場合は
port contents erlang | grep emacs
でファイルが見つかる。

GeSHiにErlangプラグイン追加
wp-syntaxでハイライト表示するために、GeSHi用のErlangプラグインを追加。下記のURLで公開されているものを利用させてもらった。

Kreisquadratur» Blog Archive » Erlang syntax highlighting for GeSHi

しかしそのままだとセミコロンが<SEMI>に変換されてしまうというバグがあるため、変数名のハイライトを諦めて下記のように修正した。

@@ -113,7 +113,7 @@
         ),
     'REGEXPS' =&gt; array(
         // Variable
-        0 =&gt; '[A-Z][_a-zA-Z0-9]*',
+        //0 =&gt; '[A-Z][_a-zA-Z0-9]*',
         // File Descriptor
         4 =&gt; '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;'
         ),

これはどちらかといえばGeSHiの仕様上の制約らしい。うまい解決策が見つかればフィードバックしたいのだが…。

『プログラミングErlang』6章まで読んだ

やっと6章まで読み終わった。いよいよ7章から並行処理に入る。

ところで6章には「コマンドライン引数を使うプログラム」の例として階乗を計算するプログラムが載っているのだが、これをそのまま実行すると引数の数が合わない場合にクラッシュダンプを吐く。流石にもうちょっと何とかならないかと思って調べてみたところ、次のようなことが分かった:

  • コマンドライン引数の数によって呼び出される関数が変わる。erl -s module func と指定した場合、コマンドライン引数を一つも与えなかった場合は module:func/0 が、一つ以上与えた場合は module:func/1 が呼び出される。
  • module:func/1の引数はアトムのリストである。
  • escriptではこの差異を吸収して、アトムをリスト(文字列)に変換した上で main/1 を呼び出している。

ということで escript の動作にあわせて次のようにしてみた。

-module(fac2).
-export([run_main/0, run_main/1]).
 
run_main()  -> main([]).
run_main(L) -> main(lists:map(fun atom_to_list/1, L)).
 
main([A]) ->
    I = list_to_integer(A),
    F = fac(I),
    io:format("factorial ~w = ~w~n", [I, F]),
    init:stop();
main(_) ->
    io:format("Usage: ~p:rum_main <num>~n", [?MODULE]),
    init:stop().
 
fac(0) -> 1;
fac(N) -> N * fac(N-1).

起動は erl -noshell -s fac2 run_main とする。


それと、6章にはMakefieのテンプレートも載っているのだが、その中の .SUFFIXES および .erl.beam といったターゲット名は古い形式の定義らしい。新しい形式では型ルールを使って次のように書けば良いようだ。

%.beam: %.erl
erlc -W $<

GNU make他類似ツールの使い方が分からない

コンパイルする言語での開発経験が皆無なこともあって、いわゆるビルドツールというやつの使い方・便利さがよく分からない。

コンパイル処理を効率化するという基礎の基礎の用途は分かる。けど現実にはこの種のビルドツールは他にも様々なタスクの自動化に用いられているわけで、そこでなぜmakeなのか、単なるシェルスクリプトでは駄目なのか、という選択基準が分からない。もしかしたらシェルスクリプトの便利なフロントエンドとして使っているだけなのかとも思ったのだが、しかし例えばRailsでは各種rakeタスクの他に、ジェネレータを起動するためのrailsコマンドは別扱いで用意されているし……むむむむむ……。

ということでいろいろ調べた結果、次のようなことを考えた:

  • make等のビルドツールの特色は依存関係を自動的に解決する、という点にある。つまり「何か」の存在を前提に、別の「何か」を得る、という仕事に特化したツールである。逆に言えば無から何かを産み出すような(ジェネレータのような)仕事には向いていない。
  • 前提となる何か(依存物)、結果として得られる何か(ターゲット)、そのための具体的な手順(コマンド)は、文字列として書き表せば共通部分が多くなる。だから様々な省略記法が用意されており、だから実物のMakefie等を見ても、慣れていないと何が書いてあるのかさっぱり分からない。

何かを前提に、何かを得る…という観点から自分が普段行っている作業を見直して、make等々で自動化することができないか、考えてみることにしよう。

XREAでWordPress 2.7

インストール自体は特に何も考えなくてもOK。safe_mode制限ありのモジュール版でも普通にインストールできる。

ただしそのままだとメディアファイルのアップロードや管理画面からのプラグインのインストールができない。少なくとも関連するphpファイルだけはCGIで動くように変更しておく必要がある(全phpをCGIで動くようにしても良い)。

具体的には、次のような .htaccess を wp-admin に置いておく。

<filesmatch "^(async-upload|plugin-install|update-core)\.php$">
  SetHandler application/x-httpd-php5cgi
</filesmatch>

それと、細かい話になるが、safe_modeオンの状態でインストールを実行するとメディアファイルのアップロード先が wp-content になってしまうので、管理画面の「設定」→「その他の設定」でアップロード先のパスをデフォルトに戻しておくこと。あと好みで「アップロードしたファイルを年月ベースのフォルダに整理」にもチェックを入れておく。

これでファイルアップロードとプラグインのインストールができることは確認した。コアのアップグレードは機会があれば試してみる。

参考:セーフモードによる制限と対処方法 WordPress Codex

(続きを読む…)

xreaって有料版なら普通にSSHが使えるんだね

昔はrbashしか使えなかったはずだが、いつの間にか有料版なら制限なしのbashが使えるようになったらしい。
http://sb.xrea.com/showthread.php?p=83744
http://sb.xrea.com/archive/index.php/t-11858.html
FAQの内容は相変わらず「DB操作のみ」となっているが、事実上は黙認なのかな…?
http://www.xrea.com/?action=faq#7

<追記>

…と、思ったら実験的な仕様だと書いてあった。
http://sb.xrea.com/showthread.php?t=9700
gccでのコンパイルについても言及されているし、とりあえず常識的な使い方をしていれば怒られることはなさそう。便利に使わせてもらうことにしよう。

本当はtdiaryを使ってみたかった

でもデフォルトでインストールされるテーマがあまりにも寂しくて、かといって自分でテンプレートとかいじる気にもなれなくて、日和ってWordPressにしてしまった。昔はガリガリとHTMLでもCSSでも書いたもんだが、時代の流れには抗えないね。