てきとう

てきとう

FizzBuzzの続き

全開^h^h前回からの続き。
また普通にFizzBuzzしても面白くないので、イテレータぽい事をやってみる。

  1. fb/1*1は前回と一緒…じゃないけど同値。(前回のが駄目すぎたとも言う)
  2. start/0で開始。
  3. fizzbuzz/1はその時点でのFizzBuzzの結果を返す。呼び出す度に一個先に進む。
  4. rpc/2は別な元ソースからの残骸w*2
  5. loop/0はloop/1のインターフェース。spawn/1に渡す関数はアリティが0じゃなきゃいけないはずなので。
  6. loop/1はreceive文とループ。rpc/12から呼び出しがあるとfb(N)を返してNを一つ進める。

ようするに、実際のところはしょぼいサーバ。

-module(fizzbuzz_serv).
%-compile(export_all).%for debug
-export([start/0,fizzbuzz/1]).

fb(N) when N rem 15=:=0->
    fizzbuzz;
fb(N) when N rem 5 =:=0->
    buzz;
fb(N) when N rem 3 =:=0->
    fizz;
fb(N)->
    N.

start()->
    spawn(fun loop/0).
fizzbuzz(Pid)->
    rpc(Pid,fizzbuzz).

rpc(Server, Request)->
    Server!{self(),Request},
    receive
	{Server,Response}->
	    Response
    end.

loop()->
    loop(1).
loop(N)->
    receive
	{From,fizzbuzz}->
	    From!{self(),fb(N)},
	    loop(N+1)
    end.

使う時はこんな感じ。
誰が何に使うのかは知らないが。

1>c(fizzbuzz_serv).
{ok,fizzbuzz_serv}
2> S=fizzbuzz_serv:start().
<0.44.0>
3> fizzbuzz_serv:fizzbuzz(S).
1
4> fizzbuzz_serv:fizzbuzz(S).
2
5> fizzbuzz_serv:fizzbuzz(S).
fizz
6> fizzbuzz_serv:fizzbuzz(S).
4
7> fizzbuzz_serv:fizzbuzz(S).
buzz
8> fizzbuzz_serv:fizzbuzz(S).
fizz
9> fizzbuzz_serv:fizzbuzz(S).
7
10> fizzbuzz_serv:fizzbuzz(S).
8
11> fizzbuzz_serv:fizzbuzz(S).
fizz
12> fizzbuzz_serv:fizzbuzz(S).
buzz
13> fizzbuzz_serv:fizzbuzz(S).
11
14> fizzbuzz_serv:fizzbuzz(S).
fizz
15> fizzbuzz_serv:fizzbuzz(S).
13
16> fizzbuzz_serv:fizzbuzz(S).
14
17> fizzbuzz_serv:fizzbuzz(S).
fizzbuzz
18> 

*1:書いていないような気もするので一応補足メモ:"foo/n"はErlang特有の関数の表記法で、「fooという名前のn個の引数を取る関数」を表す。Erlangでは引数の数(arityという)の違う関数は別なものとして扱われるため、foo/0とfoo/1とfoo/1024は全て異なる関数。

*2:プログラミングErlangの影響がでかいというか他に大した影響を受けていないのでそれに従ってたり。