YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

初めて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を関数型っぽく書く」というのが前面に押し出されている気がするのでその辺を念頭に入れて遊んで行こう。