読者です 読者をやめる 読者になる 読者になる

YAMAGUCHI::weblog

土足で窓から失礼いたします。今日からあなたの息子になります。 当年とって92歳、下町の発明王、エジソンです。

初めてErlangのコードを書いてみた

Erlang

きっかけ

自分が何か新しい言語を学ぶときにHello Worldの次にするのは

  • 何かのAPIを叩いてみる(Twitter APIなんかは簡単に試せて良い)
  • Shellコマンドを真似た何かを書いてみる

のどちらかが多いです。今回Python温泉に参加して自分がScalaではまってたときに、隣にいた@Voluntasと@kuenishiが「Erlangいいよ、Erlang」と言って、贅沢にも二人がかりで入門Erlang講座をしてくださいました。せっかくなんで帰りの東海道線でgrep的にファイルから文字列を検索して表示するというようなコードを書いてみました。

コード

こんな感じで書いてみた。

% 
% grep.erl -- find patterns from multiple files
% 
% usage: 
%      (erl)>grep:main({pattern, [file1, file2, file3, ..])
%
% version 0.1
% 
% todo:
%     1. exception processing for invalid arguments.
%     2. launch grep() as a server
%     3. logging results to a file from multiple processes
%     4. show line number if option is handed to arguments
%

-module(grep).
-compile(export_all).


main({P,T}) ->
    lists:map(fun(F) -> filep(P,F) end, T).

filep(P, F) ->
    case file:open(F, [read]) of
        {ok, Fd} ->
            Pid = spawn(grep, loop, [P, Fd]),
                io:format("~p", [Pid]);
        {error, Reason} ->
            io:format("~s : ~s", [error, Reason])
    end.
	

loop(Pattern, Fd) ->
    case file:read_line(Fd) of
        {ok, Line} -> 
            case re:run(Line, Pattern) of
                {match, _} ->
                    io:format("~p : ~s", [Pid, Line]);
                nomatch ->
                    ok
            end,
            loop(Pattern, Fd);
        eof ->
            file:close(Fd);
        _ ->
            ok
    end.

なんかすごく簡単にプロセス(グリーンスレッド)をたてられるのがすごい。このコードでは使ってないけどメッセージパッシングとかも簡単にできちゃう。(Actor Modelなのでがんがんメッセージパッシングするようになっている)
いままでこういう並列処理を前庭とした言語に触れたことがなかったので、いま触っているScalaとあわせて遊んでみたい。しかしScalaはどうしても「Javaを関数型っぽく書く」というのが前面に押し出されている気がするのでその辺を念頭に入れて遊んで行こう。