なんつーかさー、変に話題になっちゃうと途端に冷めちゃうってのが、わしのダメなところだと思うんだけども、そんな感情的な話で離れてしまうのは、あまりにもったいないと思うわけで、冷めムードではあるけど無理にでも盛り上がってみようと思ってネタプログラミングとか。
や、これ自体はたしかにネタだけど、何らかのフレームワークを作る時の叩き台にはなりそうな気はするよ。 要するに適当な粒度でもって処理をプロセス化していく仕組みにしておけば、CPU のコア数が増えたときに自動的にスケールしてくれるという感じで。
ま、それはともかく。 まずクラスを作りますヨ。
% cat oop.erl
-module(oop).
-export([counter/1]).
counter(Num) ->
put(num, if Num == undefined -> 0; true -> Num end),
receive
incr -> put(num, get(num) + 1);
print -> io:format("~p\n", [get(num)]);
{get, Pid} -> Pid ! get(num);
{[set, N], Pid} -> Pid ! put(num, N)
end,
counter(get(num)).
counter というクラスには incr, print, get, set というメソッドがあります。 読み込んでみましょう。
% erl
Erlang (BEAM) emulator version 5.5.4 [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.5.4 (abort with ^G)
1> c(oop).
{ok,oop}
インスタンス化します。
2> Obj1 = spawn(oop, counter, [10]). <0.37.0> 3> Obj2 = spawn(oop, counter, [20]). <0.39.0>
メソッドを呼んでみます。
4> Obj1 ! incr. incr 5> Obj2 ! incr. incr 6> Obj2 ! incr. incr 7> Obj2 ! incr. incr 8> Obj1 ! print. 11 print 9> Obj2 ! print. 23 print
ちゃんと状態を保持してるし、各インスタンスごとに別の状態を持ってます。
10> Obj1 ! {[set, 100], self()}.
{[set,100],<0.30.0>}
11> receive N -> ok end.
ok
set メソッドの使い方はこんな感じ。 返り値は書き換え前の値ですが、ここでは捨ててるだけ。
12> Obj1 ! print. 100 print 13> Obj2 ! print. 23 print
以上。
GUI の各部品が一つのプロセスになってるような GUI フレームワークとか作ると Smalltalk っぽくておもしろそうかも、と思った。 直接 X プロトコルを喋るポートドライバとか作れば (これ自体はすでにあるかもだけど) できそうかな、とか思うけど、誰か作んないかな。 そんな暇人はいないかね。
shiro さんが存在を教えてくれたので、ちょっと調べてみた。 そもそも X プロトコル喋るだけならソケットが使えれば良いんだから、ポートドライバとかわざわざ作らなくても、Erlang だけで書けるんだなーと気付いたときには、「おまえポートドライバ言いたいだけちゃうんか」と脳内ツッコミがぁ〜...orz
すんません、にわかもんは語りたがるんすよ。
Eshell V5.5.4 (abort with ^G)
1> cean:search(ex11).
[{"x11","New flavour of the ex11"},
{"ex11",
"This is an Erlang-X11 binding, i.e an implementation of the X11 protocol in Erlang"}]
とりあえず、cean には登録されてるみたいなので、入れてみた。
2> cean:install(ex11). + ex11 md5=<<211,131,209,44,14,178,244,85,176,108,187,55,208,99,117,145>>
……けど、何をして良いのかわからんので、まずは erlang/lib/ex11-1.5/bin/test のまねをして、rcube:start を実行してみる。
1> rcube:start(). <0.32.0>
……ダンマリ。 仕方ないのでソース読もうと思ったら cean ではソースがインストールされないみたいなので、cvsweb で閲覧。 とりあえずよくわからんのだけど、最初のとっかかりであるはずの、
4> ex11:start(localhost).
** exited: {error,econnrefused} **
ex11:start がこんな感じで失敗してるので、うちの環境の問題なのかもしれない。
懸命なる読者の方々はお気付きかもしれないが、先程 cean:search(ex11). を実行した時に ex11 の他に x11 というものもリストアップされていたのである。
というわけでさっそくインストールしてみたのだが……ナゼか中身が空っぽ。 しかたなく Jungerl のレポジトリからチェックアウトして demo.erl を動かしてみた。
% cd jungerl/lib/x11/src
% make
% erlc -I ../include demo.erl
% erl -pa ../ebin demo.beam -s demo xev
Erlang (BEAM) emulator version 5.5.4 [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.5.4 (abort with ^G)
1>
=ERROR REPORT==== 6-May-2007::20:07:47 ===
Error in process <0.30.0> with exit value: {{badmatch,{error,bad_auth}},[{demo,xev0,1}]}
うーん、やっぱだめか。
なんかソース斜め読みした感じからすると、ex11 にしても x11 にしても UNIX domain socket じゃなく IP で X サーバに接続してるように思えるんだけど、確か Mac OS X の X11.app って IP での接続を許可してなかった気がすんなー。
% xauth generate localhost:0 . xauth: (argv):1: unable to open display "localhost:0".
これって、その証拠になるんだっけ?
なんか以前は X11.app の環境設定にそこら辺の項目があったような気がするんだけど、今見ると無いね。 そろそろめんどくさくなってきたんで、これ以上の追求は気が向いたらいずれ。
あるみたいですよ>GUIの各部品がプロセス、直接Xプロトコル<br>http://www.erlang.se/workshop/2004/ex11.pdf
ありがとうございます。<br>わりと誰もが考えそうだなーとは思ってましたけど、やっぱり先人が歩いた後だったんですね(苦笑