<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>へびにっき &#187; 『プログラミングErlang』</title>
	<atom:link href="http://wp.serpere.info/archives/tag/programing_erlang/feed" rel="self" type="application/rss+xml" />
	<link>http://wp.serpere.info</link>
	<description>樹上で暮らすヘビのように生きたい</description>
	<lastBuildDate>Thu, 09 Feb 2012 11:35:51 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>トライグラム反復子</title>
		<link>http://wp.serpere.info/archives/289</link>
		<comments>http://wp.serpere.info/archives/289#comments</comments>
		<pubDate>Sun, 15 Mar 2009 12:17:43 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=289</guid>
		<description><![CDATA[『プログラミングErlang』15章本文では 単語ごとに分割する 単語の両端に空白を付加する 3文字ずつ取り出す という3段階の手順になっている。これを1段階に、すなわち先頭から順番に3文字ずつ抜き出していくアルゴリズムに変更してみた。 -define&#40;NL, $\r,$\n&#41;. &#160; % 先頭に改行を付加して処理開始 my_scan_trigrams&#40;&#91;?NL&#124;_&#93;=L, F, A&#41; -&#62; each_trigram&#40;L, F, A&#41;; my_scan_trigrams&#40;L, F, A&#41; -&#62; each_trigram&#40;&#91;?NL&#124;L&#93;, F, A&#41;. &#160; each_trigram&#40;L, F, A&#41; -&#62; case L of %% 終端の処理 &#91;?NL&#93; -&#62; A; &#91;?NL, X&#93; -&#62; F&#40;&#91;$\s, X, $\s&#93;, A&#41;; &#91;X, Y&#93; -&#62; F&#40;&#91;X, Y, $\s&#93;, A&#41;; %% 単語の先頭 &#91;?NL, X, [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F289%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E3%83%88%E3%83%A9%E3%82%A4%E3%82%B0%E3%83%A9%E3%83%A0%E5%8F%8D%E5%BE%A9%E5%AD%90%22%20%7D);"></div>
<p>『プログラミングErlang』15章本文では</p>
<ol>
<li>単語ごとに分割する</li>
<li>単語の両端に空白を付加する</li>
<li>3文字ずつ取り出す</li>
</ol>
<p>という3段階の手順になっている。これを1段階に、すなわち先頭から順番に3文字ずつ抜き出していくアルゴリズムに変更してみた。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">NL</span><span style="color: #6bb810;">,</span> $\r<span style="color: #6bb810;">,</span>$\n<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">% 先頭に改行を付加して処理開始</span>
<span style="color: #ff3c00;">my_scan_trigrams</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span>|_<span style="color: #109ab8;">&#93;</span><span style="color: #014ea4;">=</span><span style="color: #45b3e6;">L</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">each_trigram</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">L</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">my_scan_trigrams</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">L</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">each_trigram</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span>|L<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">each_trigram</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">L</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #45b3e6;">L</span> <span style="color: #186895;">of</span>
	<span style="color: #666666; font-style: italic;">%% 終端の処理</span>
	<span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span><span style="color: #109ab8;">&#93;</span>      <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">A</span><span style="color: #6bb810;">;</span>
	<span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">X</span><span style="color: #109ab8;">&#93;</span>   <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>$\s<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span> $\s<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span>   <span style="color: #45b3e6;">Y</span><span style="color: #109ab8;">&#93;</span>   <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span>   <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> $\s<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #666666; font-style: italic;">%% 単語の先頭</span>
	<span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">NL</span>|T<span style="color: #109ab8;">&#93;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">each_trigram</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span> |T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>$\s<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span> $\s<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Y</span>  |T<span style="color: #109ab8;">&#93;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">each_trigram</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Y</span>|T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>$\s<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Y</span>  <span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #666666; font-style: italic;">%% 単語の途中</span>
	<span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span>   <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">NL</span>|T<span style="color: #109ab8;">&#93;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">each_trigram</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>?<span style="color: #6941fd;">NL</span> |T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span>   <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> $\s<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span>   <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Z</span>  |T<span style="color: #109ab8;">&#93;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">each_trigram</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Z</span>|T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span>   <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Z</span>  <span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">A</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>微々たる差ではあるが、少しだけ速い。</p>
<pre>
Counting by my_scan_trigrams - No of trigrams=3357707 time/trigram=0.46476926068891655
Counting by scan_word_list - No of trigrams=3357707 time/trigram=0.5411714006016606
</pre>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/289/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>raw モードで開いたファイルの後始末</title>
		<link>http://wp.serpere.info/archives/284</link>
		<comments>http://wp.serpere.info/archives/284#comments</comments>
		<pubDate>Sat, 14 Mar 2009 08:19:58 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=284</guid>
		<description><![CDATA[先日の続き。 file:open/2 に raw オプションを指定した場合の IoDevice の実体はポート+αだった。ということは、ポートに対するBIFを使えば、プロセス終了時の挙動も確かめられるはずである。 次のようなコードで確認してみた（rpc/2 の定義は省略）。 -module&#40;raw_test&#41;. -compile&#40;export_all&#41;. &#160; start&#40;&#41; -&#62; Pid = spawn&#40;fun test/0&#41;, io:format&#40;&#34;The process which opened the file is ~p.~n&#34;, &#91;Pid&#93;&#41;, Port = rpc&#40;Pid, get&#41;, io:format&#40;&#34;The opened port is ~p.~n~n&#34;, &#91;Port&#93;&#41;, io:format&#40;&#34;is_process_alive: ~p~n&#34;, &#91;erlang:is_process_alive&#40;Pid&#41;&#93;&#41;, io:format&#40;&#34;port_info: ~p~n~n&#34;, &#91;erlang:port_info&#40;Port&#41;&#93;&#41;, rpc&#40;Pid, close&#41;, io:format&#40;&#34;is_process_alive: ~p~n&#34;, &#91;erlang:is_process_alive&#40;Pid&#41;&#93;&#41;, io:format&#40;&#34;port_info: ~p~n&#34;, &#91;erlang:port_info&#40;Port&#41;&#93;&#41;. &#160; test&#40;&#41; -&#62; %% [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F284%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22raw%20%E3%83%A2%E3%83%BC%E3%83%89%E3%81%A7%E9%96%8B%E3%81%84%E3%81%9F%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%BE%8C%E5%A7%8B%E6%9C%AB%22%20%7D);"></div>
<p><a href="http://wp.serpere.info/archives/278">先日</a>の続き。</p>
<p>file:open/2 に raw オプションを指定した場合の IoDevice の実体はポート+αだった。ということは、ポートに対するBIFを使えば、プロセス終了時の挙動も確かめられるはずである。</p>
<p>次のようなコードで確認してみた（rpc/2 の定義は省略）。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>raw_test<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">compile</span><span style="color: #109ab8;">&#40;</span>export_all<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Pid</span> <span style="color: #014ea4;">=</span> <span style="color: #fa6fff;">spawn</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span> test<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;The process which opened the file is ~p.~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #45b3e6;">Port</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">rpc</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> get<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;The opened port is ~p.~n~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;is_process_alive: ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff4e18;">erlang</span>:<span style="color: #006600;">is_process_</span><span style="color: #fa6fff;">alive</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;port_info: ~p~n~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff4e18;">erlang</span>:<span style="color: #fa6fff;">port_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">rpc</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> close<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;is_process_alive: ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff4e18;">erlang</span>:<span style="color: #006600;">is_process_</span><span style="color: #fa6fff;">alive</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;port_info: ~p~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff4e18;">erlang</span>:<span style="color: #fa6fff;">port_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">test</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #666666; font-style: italic;">%% IoDeviceのUndocumentedな内部構造に依存</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Port</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;raw_test.erl&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>read<span style="color: #6bb810;">,</span> raw<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">test</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">test</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">receive</span>
	<span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">From</span><span style="color: #6bb810;">,</span> get<span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
	    <span style="color: #45b3e6;">From</span> <span style="color: #014ea4;">!</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
	    <span style="color: #ff3c00;">test</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Port</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">From</span><span style="color: #6bb810;">,</span> close<span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
	    <span style="color: #45b3e6;">From</span> <span style="color: #014ea4;">!</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> close<span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>実行結果は次のようになった。</p>
<pre>
The process which opened the file is <0.60.0>.
The opened port is #Port<0.1695>.

is_process_alive: true
port_info: [{name,"efile"},
            {links,[<0.60.0>]},
            {id,1695},
            {connected,<0.60.0>},
            {input,9},
            {output,18}]

is_process_alive: false
port_info: undefined
</pre>
<p>ファイルを開いたプロセスが生きているときにはきちんとポートの情報が取れる。links や connected に pid が入っていることも確認できる。プロセスが終了するとポート情報は undefined となり、ポートが閉じられたことが分かる。</p>
<p>IoDevice の内部実装についてはともかく、「ファイルを開いたプロセスが終了したとき、自動的にファイルが閉じられる」という挙動については信用しても良さそうだ。例えば『プログラミングErlang』14章のSHOUTcastサーバではクライアントがTCP接続を閉じたときにコントローラプロセスがクラッシュするという仕様になっているが、このときにもきちんとファイルは close される、ということになる。</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/284/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>外部イテレータとか内部イテレータとか</title>
		<link>http://wp.serpere.info/archives/260</link>
		<comments>http://wp.serpere.info/archives/260#comments</comments>
		<pubDate>Tue, 10 Mar 2009 12:07:04 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=260</guid>
		<description><![CDATA[先日示したコード play_songs&#40;Socket, Pid, I&#41; -&#62; &#123;Bin, Header&#125; = rpc&#40;Pid, next_block&#41;, write_data&#40;Socket, Bin, &#123;I, Header&#125;&#41;, play_songs&#40;Socket, Pid, I+1&#41;. これは形式的には「外部イテレータ」のように見える。 そして「内部イテレータ」の形式に書き換えることもできる。 play_songs&#40;Socket&#41; -&#62; each_song_block&#40;fun&#40;Bin, Header, I&#41; -&#62; write_data&#40;Socket, Bin, &#123;I, Header&#125;&#41;, I+1 end, 0&#41;. この場合は別プロセスを立ち上げる必要は無い。逆に考えると、プロセスとメッセージパッシングの考え方を用いることで、内部イテレータ（的な処理）を外部イテレータ（的な処理）に書き換えることができる……と言えそうである。 内部イテレータを外部イテレータに、という話題では、確か「コルーチン」が云々という議論があったはず……と思って検索してみたら、案の定興味深いページがいろいろと見つかった。 メイン・ルーチン、サブルーチンそしてコルーチン [Think IT]第4回：並列処理が可能な関数型言語「Erlang」 アクターモデル &#8211; Wikipedia マルチプロセスとメッセージパッシングによる真の並列性を備えたErlangならば、コルーチンと同等の構造も容易に作れる……という理解で良いのだろうか。]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F260%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E5%A4%96%E9%83%A8%E3%82%A4%E3%83%86%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%A8%E3%81%8B%E5%86%85%E9%83%A8%E3%82%A4%E3%83%86%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%A8%E3%81%8B%22%20%7D);"></div>
<p><a href="http://wp.serpere.info/archives/255">先日</a>示したコード</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">play_songs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">I</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Header</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">rpc</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> next_block<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">write_data</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">I</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Header</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">play_songs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">I</span><span style="color: #014ea4;">+</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>これは形式的には「外部イテレータ」のように見える。</p>
<p>そして「内部イテレータ」の形式に書き換えることもできる。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">play_songs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
   <span style="color: #ff3c00;">each_song_block</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Header</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">I</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
                            <span style="color: #ff3c00;">write_data</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">I</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Header</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
                            <span style="color: #45b3e6;">I</span><span style="color: #014ea4;">+</span><span style="color: #ff9600;">1</span>
                    <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>この場合は別プロセスを立ち上げる必要は無い。逆に考えると、プロセスとメッセージパッシングの考え方を用いることで、内部イテレータ（的な処理）を外部イテレータ（的な処理）に書き換えることができる……と言えそうである。</p>
<p>内部イテレータを外部イテレータに、という話題では、確か「コルーチン」が云々という議論があったはず……と思って検索してみたら、案の定興味深いページがいろいろと見つかった。</p>
<ul>
<li><a href="http://madeira.cc.hokudai.ac.jp/RD/yamamoto/Essay/11.html">メイン・ルーチン、サブルーチンそしてコルーチン</a></li>
<li><a href="http://www.thinkit.co.jp/cert/article/0711/4/4/3.htm">[Think IT]第4回：並列処理が可能な関数型言語「Erlang」</a></li>
<li><a href="http://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%AF%E3%82%BF%E3%83%BC%E3%83%A2%E3%83%87%E3%83%AB">アクターモデル &#8211; Wikipedia</a></li>
</ul>
<p>マルチプロセスとメッセージパッシングによる真の並列性を備えたErlangならば、コルーチンと同等の構造も容易に作れる……という理解で良いのだろうか。</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/260/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>14章SHOUTcastサーバのリファクタリング</title>
		<link>http://wp.serpere.info/archives/255</link>
		<comments>http://wp.serpere.info/archives/255#comments</comments>
		<pubDate>Fri, 06 Mar 2009 12:40:24 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=255</guid>
		<description><![CDATA[14.7の『SHOUTcastサーバ』はこの本の中で2番目の山場だと思う。send_file/5 とか、処理の見通しが悪過ぎて投げ出したくなった……。が、頑張ってなんとか読み進めている。 まず「ファイルの中の、ある範囲内にランダムアクセスする」処理を分離したい。というわけで次のようなモジュールを書いた。一見して明らかなように、露骨にOOを意識している。 -module&#40;filerange&#41;. -export&#40;&#91;open/2, close/1, pread/3&#93;&#41;. -record&#40;file_with_range, &#123; io, min, max &#125;&#41;. &#160; open&#40;File, Min, Max&#41; -&#62; &#123;ok, Io&#125; = file:open&#40;File, &#91;read, binary, raw&#93;&#41;, #file_with_range&#123;io=Io, min=Min, max=Max&#125;. &#160; close&#40;#file_with_range&#123;io=Io&#125;&#41; -&#62; file:close&#40;Io&#41;. &#160; pread&#40;#file_with_range&#123;io=Io, min=Min, max=Max&#125;, Offset, Size&#41; -&#62; Start = Min + Offset, End = Start + Size, if End &#62; Max -&#62; case [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F255%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%2214%E7%AB%A0SHOUTcast%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0%22%20%7D);"></div>
<p>14.7の『SHOUTcastサーバ』はこの本の中で2番目の山場だと思う。send_file/5 とか、処理の見通しが悪過ぎて投げ出したくなった……。が、頑張ってなんとか読み進めている。</p>
<p>まず「ファイルの中の、ある範囲内にランダムアクセスする」処理を分離したい。というわけで次のようなモジュールを書いた。一見して明らかなように、露骨にOOを意識している。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>filerange<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>open<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> close<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> pread<span style="color: #014ea4;">/</span><span style="color: #ff9600;">3</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">file_with_range</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span> io<span style="color: #6bb810;">,</span> min<span style="color: #6bb810;">,</span> max <span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">File</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Min</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Max</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Io</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">File</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>read<span style="color: #6bb810;">,</span> <span style="color: #fa6fff;">binary</span><span style="color: #6bb810;">,</span> raw<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    #<span style="color: #d400ed;">file_with_range</span><span style="color: #109ab8;">&#123;</span>io<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> min<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Min</span><span style="color: #6bb810;">,</span> max<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Max</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span>#<span style="color: #d400ed;">file_with_range</span><span style="color: #109ab8;">&#123;</span>io<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Io</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span>#<span style="color: #d400ed;">file_with_range</span><span style="color: #109ab8;">&#123;</span>io<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> min<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Min</span><span style="color: #6bb810;">,</span> max<span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Max</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Offset</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Size</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Start</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Min</span> <span style="color: #014ea4;">+</span> <span style="color: #45b3e6;">Offset</span><span style="color: #6bb810;">,</span>
    <span style="color: #45b3e6;">End</span>   <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Start</span> <span style="color: #014ea4;">+</span> <span style="color: #45b3e6;">Size</span><span style="color: #6bb810;">,</span>
    <span style="color: #186895;">if</span>
	<span style="color: #45b3e6;">End</span> <span style="color: #014ea4;">&gt;</span> <span style="color: #45b3e6;">Max</span> <span style="color: #6bb810;">-&gt;</span>
	    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Start</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Max</span> <span style="color: #014ea4;">-</span> <span style="color: #45b3e6;">Start</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
		<span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#123;</span>less<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
		eof <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#123;</span>less<span style="color: #6bb810;">,</span> <span style="color: #ee3800;">&lt;&lt;&gt;&gt;</span><span style="color: #109ab8;">&#125;</span>
	    <span style="color: #186895;">end</span><span style="color: #6bb810;">;</span>
	true <span style="color: #6bb810;">-&gt;</span>
	    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Start</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Size</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
	    <span style="color: #109ab8;">&#123;</span>exact<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>しかしこれではイマイチだ。グローバルなモジュールの名前空間を占有する割には、さほど汎用的なコードではない。というか別に汎用的にするつもりもない。単に処理のスコープを分割したいだけだ。しかしそういう気軽な分割に用いるには、モジュールという単位は大げさ過ぎる……。</p>
<p>そこでふと、<a href="http://wp.serpere.info/archives/149">以前</a>に「<strong>様々なプログラミングパラダイムを全てプロセスとメッセージ送信に還元していくのがErlang流だ</strong>」と考えたことを思い出した。そうだ、これも別プロセスで動かしてしまおう！</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">filerange_server</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">File</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Min</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Max</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Io</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">File</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>read<span style="color: #6bb810;">,</span> <span style="color: #fa6fff;">binary</span><span style="color: #6bb810;">,</span> raw<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">filerange_loop</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Min</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Max</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">filerange_loop</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Min</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Max</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">receive</span>
	<span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">From</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>pread<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Offset</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Size</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
	    <span style="color: #45b3e6;">Start</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Min</span> <span style="color: #014ea4;">+</span> <span style="color: #45b3e6;">Offset</span><span style="color: #6bb810;">,</span>
	    <span style="color: #45b3e6;">End</span>   <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Start</span> <span style="color: #014ea4;">+</span> <span style="color: #45b3e6;">Size</span><span style="color: #6bb810;">,</span>
	    <span style="color: #186895;">if</span>
		<span style="color: #45b3e6;">End</span> <span style="color: #014ea4;">&gt;</span> <span style="color: #45b3e6;">Max</span> <span style="color: #6bb810;">-&gt;</span>
		    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Start</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Max</span> <span style="color: #014ea4;">-</span> <span style="color: #45b3e6;">Start</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
			<span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">From</span> <span style="color: #014ea4;">!</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>less<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
			eof        <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">From</span> <span style="color: #014ea4;">!</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>less<span style="color: #6bb810;">,</span> <span style="color: #ee3800;">&lt;&lt;&gt;&gt;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span>
		    <span style="color: #186895;">end</span><span style="color: #6bb810;">;</span>
		true <span style="color: #6bb810;">-&gt;</span>
		    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Start</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Size</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
		    <span style="color: #45b3e6;">From</span> <span style="color: #014ea4;">!</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>exact<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span>
	    <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
	    <span style="color: #ff3c00;">filerange_loop</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Min</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Max</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">From</span><span style="color: #6bb810;">,</span> close<span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
	    <span style="color: #45b3e6;">From</span> <span style="color: #014ea4;">!</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Io</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>これで名前空間は適切に分割され、汎用の rpc で呼び出せるようになった。デバッグも簡単だ。</p>
<pre>
erl> Pid = spawn(fun() -> myshout:filerange_server("AtoZ.txt", 5, 20) end).
<0.37.0>

erl> myshout:rpc(Pid, {pread, 0, 5}).
{exact,<<"FGHIJ">>}

erl> myshout:rpc(Pid, {pread, 10, 5}).
{exact,<<"PQRST">>}

erl> myshout:rpc(Pid, {pread, 0, 100}).
{less,<<"FGHIJKLMNOPQRST">>}
</pre>
<p>さらに調子に乗って play_songs/3 の中の曲選択部分も別プロセスとして分離した結果、「曲データを無限に読み出し続ける」という処理は次のように簡潔な記述になった。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">play_songs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">I</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Header</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">rpc</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> next_block<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">write_data</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">I</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Header</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">play_songs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Socket</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">I</span><span style="color: #014ea4;">+</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>いい感じだ。何となくErlangのプロセスの面白さが分かってきた気がする。</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/255/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Erlangの正規表現について調べる（2）</title>
		<link>http://wp.serpere.info/archives/234</link>
		<comments>http://wp.serpere.info/archives/234#comments</comments>
		<pubDate>Sun, 15 Feb 2009 13:47:46 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=234</guid>
		<description><![CDATA[先日コメント欄で教えていただいたErlangの新しい正規表現モジュール re。使える正規表現の種類やマッチの特性・性能は PCRE に準ずるので、現代的な諸プログラミング言語と比較しても遜色ないレベルの機能を備えている。正規表現なしの文字列処理なんて考えられない！という人もこれで安心。 さらに、古い regexp モジュールと比較して、マッチ対象や正規表現自体を iodata() で構成することができるという点は注目に値する。 erl> re:run([, $m, "i ", [, "ka"]], ["^", "A.+a", "$"]). {match,[{0,12}]} マッチや置換の結果を取得する方法も柔軟に選択できるので、「一連のバイナリから特定のパターンを抜き出してリスト（文字列）として取得する」なんてことも簡単にできる。例えば『プログラミングErlang』193ページの scavenge_urls:gather_urls は次のように書き換えられる。 gather_urls&#40;Bin&#41; -&#62; case re:run&#40;Bin, &#34;&#60;a href.+?&#60;/a&#62;&#34;, &#91;global, dotall, &#123;capture, first, list&#125;&#93;&#41; of &#123;match, L&#125; -&#62; L; _ -&#62; &#91;&#93; end. id3_v1:trim も次の通り簡潔に。 trim&#40;Bin&#41; -&#62; re:replace&#40;Bin, &#34;[ \\0]+$&#34;, &#34;&#34;, &#91;&#123;return, binary&#125;&#93;&#41;. … ちなみに [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F234%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Erlang%E3%81%AE%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%AA%BF%E3%81%B9%E3%82%8B%EF%BC%882%EF%BC%89%22%20%7D);"></div>
<p><a href="http://wp.serpere.info/archives/215">先日</a>コメント欄で教えていただいたErlangの新しい正規表現モジュール <a href="http://erlang.org/doc/man/re.html">re</a>。使える正規表現の種類やマッチの特性・性能は PCRE に準ずるので、現代的な諸プログラミング言語と比較しても遜色ないレベルの機能を備えている。正規表現なしの文字列処理なんて考えられない！という人もこれで安心。</p>
<p>さらに、古い regexp モジュールと比較して、マッチ対象や正規表現自体を iodata() で構成することができるという点は注目に値する。</p>
<pre>
erl> re:run([<<"Ama">>, $m, "i ", [<<"Haru">>, "ka"]], ["^", "A.+a", "$"]).
{match,[{0,12}]}
</pre>
<p>マッチや置換の結果を取得する方法も柔軟に選択できるので、「一連のバイナリから特定のパターンを抜き出してリスト（文字列）として取得する」なんてことも簡単にできる。例えば『プログラミングErlang』193ページの scavenge_urls:gather_urls は次のように書き換えられる。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">gather_urls</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">re</span>:<span style="color: #ff3c00;">run</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;&lt;a href.+?&lt;/a&gt;&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>global<span style="color: #6bb810;">,</span> dotall<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>capture<span style="color: #6bb810;">,</span> first<span style="color: #6bb810;">,</span> <span style="color: #fa6fff;">list</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
	<span style="color: #109ab8;">&#123;</span>match<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">L</span><span style="color: #6bb810;">;</span>
	<span style="color: #45b3e6;">_</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>id3_v1:trim も次の通り簡潔に。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">trim</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">re</span>:<span style="color: #ff3c00;">replace</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;[ <span style="color: #000099; font-weight: bold;">\\</span>0]+$&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>return<span style="color: #6bb810;">,</span> <span style="color: #fa6fff;">binary</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>…<br />
ちなみに re モジュールは<a href="http://www.erlang.org/eeps/eep-0011.html">EEP(Erlang Enhancement Proposal) 11</a>として提案され、R12B-3において実験的なモジュールとして取り込まれたようだ。Erlangは今なお活発に開発が続けられているんだなあ…。『プログラミングErlang』はR11B-5を基準に書かれているから、たまには最新情報をチェックしていかなくては。</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/234/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erlangの正規表現について調べる</title>
		<link>http://wp.serpere.info/archives/215</link>
		<comments>http://wp.serpere.info/archives/215#comments</comments>
		<pubDate>Wed, 11 Feb 2009 14:57:54 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=215</guid>
		<description><![CDATA[みんな大好き正規表現が13章で初登場。Erlangのregexpモジュールについて調べてみた。 （追記：コメント欄にて、PCREベースの新しい正規表現モジュール re の存在を教えてもらいました。こちらも後で調べてみます） 実装・性能 regexpモジュールはErlnagで実装されている。code:which(regexp) でソースファイルを探してコメントを読んでみると、NFAに変換せずに独自の内部表現とパターンマッチで実装されているらしい（その方がずっと速いから、とのこと）。内部表現は regexp:parse を使って確認することができる。 erlang> regexp:parse("xxx&#124;yyy"). {ok,{'or',{concat,{concat,120,120},120}, {concat,{concat,121,121},121}}} この実装を読み解いてみるのも面白いかも知れない。 ただし独自実装の宿命として、機能は貧弱だし遅い。本家ドキュメントのEfficiency Guide 3.1にも Don&#8217;t use the regexp module in time-critical code. と書いてある。 マッチの性質 正規表現によるマッチを行う関数として、match と first_match という2種類の関数が用意されている。 first_match は最も左でマッチした結果を返す（最左マッチ） match は文字列中の全ての位置でマッチを行い、最も長くマッチした結果を返す erlang> regexp:first_match("xx xxxx xxxxxx", "x+"). {match,1,2} erlang> regexp:match("xx xxxx xxxxxx", "x+"). {match,9,6} first_match の方が速いので、単にマッチするかどうか調べるだけなら first_match を使った方が良い。 またどちらの関数も、その位置でマッチする最長のものを見つけようとする（最長マッチ）。 erlang> regexp:first_match("xxxxyyyy", "x+(yy)?(yyyy)?"). [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F215%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Erlang%E3%81%AE%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%AA%BF%E3%81%B9%E3%82%8B%22%20%7D);"></div>
<p>みんな大好き正規表現が13章で初登場。Erlangのregexpモジュールについて調べてみた。</p>
<p>（追記：コメント欄にて、PCREベースの新しい正規表現モジュール <a href="http://erlang.org/doc/man/re.html">re</a> の存在を教えてもらいました。こちらも後で調べてみます）</p>
<h3>実装・性能</h3>
<p>regexpモジュールはErlnagで実装されている。code:which(regexp) でソースファイルを探してコメントを読んでみると、NFAに変換せずに独自の内部表現とパターンマッチで実装されているらしい（その方がずっと速いから、とのこと）。内部表現は regexp:parse を使って確認することができる。</p>
<pre>
erlang> regexp:parse("xxx|yyy").
{ok,{'or',{concat,{concat,120,120},120},
          {concat,{concat,121,121},121}}}
</pre>
<p>この実装を読み解いてみるのも面白いかも知れない。</p>
<p>ただし独自実装の宿命として、機能は貧弱だし遅い。本家ドキュメントの<a href="http://erlang.org/doc/efficiency_guide/part_frame.html">Efficiency Guide</a> 3.1にも <q>Don&#8217;t use the regexp module in time-critical code. </q>と書いてある。</p>
<h3>マッチの性質</h3>
<p>正規表現によるマッチを行う関数として、match と first_match という2種類の関数が用意されている。</p>
<ul>
<li>first_match は最も左でマッチした結果を返す（最左マッチ）</li>
<li>match は文字列中の全ての位置でマッチを行い、最も長くマッチした結果を返す</li>
</ul>
<pre>
erlang> regexp:first_match("xx xxxx xxxxxx", "x+").
{match,1,2}
erlang> regexp:match("xx xxxx xxxxxx", "x+").
{match,9,6}
</pre>
<p>first_match の方が速いので、単にマッチするかどうか調べるだけなら first_match を使った方が良い。</p>
<p>またどちらの関数も、その位置でマッチする最長のものを見つけようとする（最長マッチ）。</p>
<pre>
erlang> regexp:first_match("xxxxyyyy", "x+(yy)?(yyyy)?").
{match,1,8}
</pre>
<p>よって first_match は、いわゆるPOSIX NFAと同じ最長最左マッチを行うことになる。これは perl や ruby など従来型NFAとは異なる動作である。</p>
<pre>
irb> $&#038; if /x+(yy)?(yyyy)?/ =~ "xxxxyyyy"
=> "xxxxyy"
</pre>
<h3>lib_find:files/5 の改善</h3>
<p>『13.8 findユーティリティ』に出てくる lib_find:files/5 がイマイチだと感じたので、自分なりに修正してみた。以下の点を変更している。</p>
<ul>
<li>regexp:match/2 の代わりに regexp:first_match/2 を使うようにした</li>
<li>accumulator の処理を lists:foldl/3 に委託した</li>
<li>マッチ対象を「ファイルの完全パス」から「ファイル名」に変更した</li>
</ul>
<p><span id="more-215"></span></p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">files</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Dir</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">RegExp</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Recursive</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Fun</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Acc0</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">foldl</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Acc</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
		  <span style="color: #45b3e6;">FullPath</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">filename</span>:<span style="color: #ff3c00;">join</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Dir</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
		  <span style="color: #186895;">case</span> <span style="color: #ff3c00;">file_type</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">FullPath</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
		      regular <span style="color: #6bb810;">-&gt;</span>
			  <span style="color: #ff3c00;">apply_if_match</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">FullPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Acc</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">RegExp</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
		      directory <span style="color: #186895;">when</span> <span style="color: #45b3e6;">Recursive</span> <span style="color: #014ea4;">=:=</span> true <span style="color: #6bb810;">-&gt;</span>
			  <span style="color: #ff3c00;">files</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">FullPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">RegExp</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Recursive</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Fun</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Acc</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
		      <span style="color: #45b3e6;">_</span> <span style="color: #6bb810;">-&gt;</span>
			  <span style="color: #45b3e6;">Acc</span>
		  <span style="color: #186895;">end</span>
	  <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
	  <span style="color: #45b3e6;">Acc0</span><span style="color: #6bb810;">,</span>
	  <span style="color: #186895;">case</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">list_dir</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Dir</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
	     <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Files</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">Files</span><span style="color: #6bb810;">;</span>
	      <span style="color: #45b3e6;">_</span>          <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span>
	  <span style="color: #186895;">end</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">apply_if_match</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Arg1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Acc</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Str</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">RegExp</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">regexp</span>:<span style="color: #ff3c00;">first_match</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Str</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">RegExp</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
	<span style="color: #109ab8;">&#123;</span>match<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">F</span><span style="color: #ff3c00;">un</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Acc</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
	<span style="color: #45b3e6;">_</span>             <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">Acc</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>




]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/215/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>『9.8 キープアライブプロセス』徹底理解(2)</title>
		<link>http://wp.serpere.info/archives/202</link>
		<comments>http://wp.serpere.info/archives/202#comments</comments>
		<pubDate>Tue, 03 Feb 2009 10:26:46 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=202</guid>
		<description><![CDATA[先日の続き。 実は書いているうちに新たな疑問が浮かんできて、再度考え直していた。その結果、先日の内容には少し嘘が含まれていたことにも気付いた（詳細は「問題点4」の中で）。やっぱり「徹底検証」だとか格好つけるもんじゃないね！ 問題点3. 同じNameでkeep_aliveを評価するのは競合ではない 「問題点2」の考察の中では即死するプロセスとsleepを使って意図的に競合状態を起こしてみたわけだが、本文中では次のような場合に競合が起こると説明されている。 そのような状況は2つのプロセスがNameに同じ値を指定して同時にkeep_aliveを評価しようとすると発生する。この状況は競合状態と呼ばれる。2つのコード（上記のコードと、on_exitの中でリンク操作を実行する部分）がお互いにリンク操作を取りあってしまう状態だ。ここで問題が起きると、プログラムは期待通りには動かないだろう。 しかしこれは変だ。複数のプロセスが同じ Name で keep_alive を呼び出せば確かにプログラムは正しく動かないだろうが、それは単に重複する名前で register/2 を呼んだからであって、競合状態とは何の関係もない。 register に失敗した場合 on_exit は評価されないのだから、リンク操作自体実行されない →「競い合う」要素がない register に失敗したとき死ぬのは register の呼び出し元プロセスであって、登録されつつある当のプロセスではない → リンクの成否に関わらず、on_exit が意味をもつような状況にはならない よってこの部分の説明は、単純に勘違いによって挿入されたものだと思われる。 問題点4. spawn と register が競合する可能性 競合が起こるのはむしろ spawn と register の方なのだ。すなわち Pid = spawn&#40;Fun&#41;, register&#40;Name, Pid&#41;, この2つの文の間でプロセスが死んでしまうと、死んだプロセスを登録しようとして register がエラーを起こし、プログラムの実行が停止する。 ……実は先日「問題点2」を検証する中で行った実験では、この競合が起こる可能性があった。もし競合が起こった場合 keep_alive が停止して、「1秒おきに延々と再起動が繰り返される」という説明は嘘になる。確認が足りなくて恐縮。 とはいえ、単に即死するプロセスを登録したくらいではなかなか再現されないようだ。 1> Pid = spawn(fun() -> 1 end), [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F202%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E3%80%8E9.8%20%E3%82%AD%E3%83%BC%E3%83%97%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%96%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%80%8F%E5%BE%B9%E5%BA%95%E7%90%86%E8%A7%A3%282%29%22%20%7D);"></div>
<p><a href="http://wp.serpere.info/archives/192">先日</a>の続き。</p>
<p>実は書いているうちに新たな疑問が浮かんできて、再度考え直していた。その結果、先日の内容には少し嘘が含まれていたことにも気付いた（詳細は「問題点4」の中で）。やっぱり「徹底検証」だとか格好つけるもんじゃないね！</p>
<p><span id="more-202"></span></p>
<h3>問題点3. 同じNameでkeep_aliveを評価するのは競合ではない</h3>
<p>「問題点2」の考察の中では即死するプロセスとsleepを使って意図的に競合状態を起こしてみたわけだが、本文中では次のような場合に競合が起こると説明されている。</p>
<blockquote><p>
そのような状況は2つのプロセスがNameに同じ値を指定して同時にkeep_aliveを評価しようとすると発生する。この状況は競合状態と呼ばれる。2つのコード（上記のコードと、on_exitの中でリンク操作を実行する部分）がお互いにリンク操作を取りあってしまう状態だ。ここで問題が起きると、プログラムは期待通りには動かないだろう。
</p></blockquote>
<p>しかしこれは変だ。複数のプロセスが同じ Name で keep_alive を呼び出せば確かにプログラムは正しく動かないだろうが、それは単に重複する名前で register/2 を呼んだからであって、競合状態とは何の関係もない。</p>
<ul>
<li>register に失敗した場合 on_exit は評価されないのだから、リンク操作自体実行されない<br />
→「競い合う」要素がない</li>
<li>register に失敗したとき死ぬのは register の呼び出し元プロセスであって、登録されつつある当のプロセスではない<br />
→ リンクの成否に関わらず、on_exit が意味をもつような状況にはならない</li>
</ul>
<p>よってこの部分の説明は、単純に勘違いによって挿入されたものだと思われる。</p>
<h3>問題点4. spawn と register が競合する可能性</h3>
<p>競合が起こるのはむしろ spawn と register の方なのだ。すなわち</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #45b3e6;">Pid</span> <span style="color: #014ea4;">=</span> <span style="color: #fa6fff;">spawn</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #fa6fff;">register</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span></pre></div></div>



<p>この2つの文の間でプロセスが死んでしまうと、死んだプロセスを登録しようとして register がエラーを起こし、プログラムの実行が停止する。</p>
<p><strong>……実は先日「問題点2」を検証する中で行った実験では、この競合が起こる可能性があった</strong>。もし競合が起こった場合 keep_alive が停止して、「1秒おきに延々と再起動が繰り返される」という説明は嘘になる。確認が足りなくて恐縮。</p>
<p>とはいえ、単に即死するプロセスを登録したくらいではなかなか再現されないようだ。</p>
<pre>
1> Pid = spawn(fun() -> 1 end), register(foo, Pid).
true
</pre>
<p>適当にスリープを入れたり別の処理を挟めば再現できる。</p>
<pre>
2> Pid2 = spawn(fun() -> 1 end), lib_misc:sleep(10), register(foo, Pid2).
** exception error: bad argument
     in function  register/2
        called as register(foo,<0.54.0>)
</pre>
<h3>結局どうすれば良いのか？</h3>
<p>競合が起こり得る組み合わせは少なくとも2つある。</p>
<ul>
<li>spawn と link</li>
<li>spawn と register</li>
</ul>
<p>これらをアトミックに実行するための仕組みを用意すれば良い。前者は組み込みの spawn_link であり、後者は演習8.11がヒントとなる。</p>
<p>私なりの on_exit と keep_alive の改良は次のようになった。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">on_fun_<span style="color: #fa6fff;">exit</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Handler</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #fa6fff;">spawn</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
                  <span style="color: #fa6fff;">process_flag</span><span style="color: #109ab8;">&#40;</span>trap_exit<span style="color: #6bb810;">,</span> true<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
                  <span style="color: #45b3e6;">Pid</span> <span style="color: #014ea4;">=</span> <span style="color: #fa6fff;">spawn_link</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
                  <span style="color: #186895;">receive</span>
                      <span style="color: #109ab8;">&#123;</span><span style="">'EXIT'</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Why</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
                          <span style="color: #45b3e6;">H</span><span style="color: #ff3c00;">andler</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Why</span><span style="color: #109ab8;">&#41;</span>
                  <span style="color: #186895;">end</span>
          <span style="color: #186895;">end</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
keep_<span style="color: #fa6fff;">alive</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #006600;">on_fun_</span><span style="color: #fa6fff;">exit</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
                        <span style="color: #186895;">try</span> <span style="color: #fa6fff;">register</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #fa6fff;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
                            true <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">F</span><span style="color: #ff3c00;">un</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span>
                        <span style="color: #186895;">catch</span>
                            error:<span style="color: #006600;">badarg</span> <span style="color: #6bb810;">-&gt;</span>
                                <span style="color: #fa6fff;">exit</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span>already_running<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Name</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span>
                        <span style="color: #186895;">end</span>
                <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
                <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Why</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #666666; font-style: italic;">%io:format(&quot;~p exit with ~p, try to restart~n&quot;, [_Pid, _Why]),</span>
                                   keep_<span style="color: #fa6fff;">alive</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>on_exit の中で spawn に換えて spawn_link を使っているので、対象プロセスが即死してもきちんと死因が採れる。また Fun は register の後に実行されるので、死んだプロセスを登録するようなこともない。またその副作用として、同じ名前で register を呼んだ場合のエラーも捕捉できるようになっている。</p>
<p>演習8.11の解答に相当する部分は、全面的に<a href="http://www.nabble.com/Programming-Erlang-Exercise-8.11-to12791301.html#a12791301">こちらのフォーラムの解答</a>によっている。</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/202/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>『9.8 キープアライブプロセス』徹底検証</title>
		<link>http://wp.serpere.info/archives/192</link>
		<comments>http://wp.serpere.info/archives/192#comments</comments>
		<pubDate>Sun, 01 Feb 2009 13:46:00 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=192</guid>
		<description><![CDATA[『プログラミングErlang』138ページ。この1ページを理解するのに丸一日以上要したのは、単に私の頭が鈍いから、というだけではない！と思ったので、これから2回に分けて徹底的に検証していくことにする。 問題となる部分の引用： on_exitとkeep_aliveにはちょっとした間違いがあるのに気付いただろうか？次のようなコードを書くと： Pid = register(&#8230;), on_exit(Pid, fun(X) -> ..), この2つの文の間でプロセスが死んでしまう可能性がある。on_exitが評価される前にプロセスが死ぬとリンクは作られないので、on_exitプロセスは期待どおりの仕事をしてくれなくなる。そのような状況は2つのプロセスがNameに同じ値を指定して同時にkeep_aliveを評価しようとすると発生する。この状況は競合状態と呼ばれる。2つのコード（上記のコードと、on_exitの中でリンク操作を実行する部分）がお互いにリンク操作を取りあってしまう状態だ。ここで問題が起きると、プログラムは期待通りには動かないだろう。 問題点1. コードが間違っている まず明らかに、文中のコードは間違っている。register/2 の戻り値は true なのだから、それを Pid という変数で受けて on_exit の引数に渡すのはおかしい。keep_alive 本来のコードは次のようになっている： register&#40;Name, Pid = spawn&#40;Fun&#41;&#41;, on_exit&#40;Pid, fun&#40;Why&#41; -&#62; ..&#41;, おそらく spawn と register の部分を次のように書き下そうとして間違えたのだろう。 Pid = spawn&#40;Fun&#41;, register&#40;Name, Pid&#41;, on_exit&#40;Pid, fun&#40;Why&#41; -&#62; ..&#41;, つまり作者がここで言わんとしているのは、「spawn してから link するまでにプロセスが死ぬ可能性がある」ということだと思われる。『9.2 on_exitハンドラ』のNoteや9.5の spawn_link の説明にも同趣旨のことが書いてある。 問題点2. on_exit は正常に動作しないが、keep_alive は期待通りに動く [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F192%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E3%80%8E9.8%20%E3%82%AD%E3%83%BC%E3%83%97%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%96%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%80%8F%E5%BE%B9%E5%BA%95%E6%A4%9C%E8%A8%BC%22%20%7D);"></div>
<p>『プログラミングErlang』138ページ。この1ページを理解するのに丸一日以上要したのは、単に私の頭が鈍いから、というだけではない！と思ったので、これから2回に分けて徹底的に検証していくことにする。</p>
<p>問題となる部分の引用：</p>
<blockquote><p>
on_exitとkeep_aliveにはちょっとした間違いがあるのに気付いただろうか？次のようなコードを書くと：</p>
<p>Pid = register(&#8230;),<br />
on_exit(Pid, fun(X) -> ..),</p>
<p>この2つの文の間でプロセスが死んでしまう可能性がある。on_exitが評価される前にプロセスが死ぬとリンクは作られないので、on_exitプロセスは期待どおりの仕事をしてくれなくなる。そのような状況は2つのプロセスがNameに同じ値を指定して同時にkeep_aliveを評価しようとすると発生する。この状況は競合状態と呼ばれる。2つのコード（上記のコードと、on_exitの中でリンク操作を実行する部分）がお互いにリンク操作を取りあってしまう状態だ。ここで問題が起きると、プログラムは期待通りには動かないだろう。
</p></blockquote>
<p><span id="more-192"></span></p>
<h3>問題点1. コードが間違っている</h3>
<p>まず明らかに、文中のコードは間違っている。register/2 の戻り値は true なのだから、それを Pid という変数で受けて on_exit の引数に渡すのはおかしい。keep_alive 本来のコードは次のようになっている：</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #fa6fff;">register</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span> <span style="color: #014ea4;">=</span> <span style="color: #fa6fff;">spawn</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  on_<span style="color: #fa6fff;">exit</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Why</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #6bb810;">..</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span></pre></div></div>



<p>おそらく spawn と register の部分を次のように書き下そうとして間違えたのだろう。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #45b3e6;">Pid</span> <span style="color: #014ea4;">=</span> <span style="color: #fa6fff;">spawn</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #fa6fff;">register</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  on_<span style="color: #fa6fff;">exit</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Why</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #6bb810;">..</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span></pre></div></div>



<p>つまり作者がここで言わんとしているのは、「spawn してから link するまでにプロセスが死ぬ可能性がある」ということだと思われる。『9.2 on_exitハンドラ』のNoteや9.5の spawn_link の説明にも同趣旨のことが書いてある。</p>
<h3>問題点2. on_exit は正常に動作しないが、keep_alive は期待通りに動く</h3>
<p>さて、確かに spawn から on_exit（の中で呼び出されるlink）の間にプロセスが死ぬと on_exit は正しく動かなくなる。しかし<strong> keep_alive は期待通りに動いてしまう</strong>。つまりどのタイミングでプロセスが死んでも、必ず再起動される。</p>
<p>それを確かめるために次のような即座に終了する関数を keep_alive に与えてみよう。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #45b3e6;">F</span> <span style="color: #014ea4;">=</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff9600;">1</span><span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>念を入れて spawn と on_exit の間に1秒のスリープを入れておく（私の環境では入れなくても結果は同じだった）。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">keep_<span style="color: #fa6fff;">alive</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #fa6fff;">register</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span> <span style="color: #014ea4;">=</span> <span style="color: #fa6fff;">spawn</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">sleep</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff9600;">1000</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    on_<span style="color: #fa6fff;">exit</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_Why</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">keep_</span><span style="color: #fa6fff;">alive</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Name</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>これを実行してみれば、1秒おきに延々と再起動が繰り返されるのが確認できる（※）。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">lib_mis<span style="color: #ff4e18;">c</span>:<span style="color: #006600;">keep_</span><span style="color: #fa6fff;">alive</span><span style="color: #109ab8;">&#40;</span>suicide<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>なぜこのような動作になるかと言うと、システムプロセスが既に死んだプロセスに対して link すると、&#8217;noproc&#8217; を原因として死んだかのような死亡通知メッセージが届くからだ（詳しくは<a href="http://wp.serpere.info/archives/104">以前の日記</a>を参照）。</p>
<p>プロセスの本来の死因は link した時点では既に失われてしまっているから、on_exit 本来の機能としては不完全だろう。だから「<q>on_exitプロセスは期待どおりの仕事をしてくれなくなる</q>」という説明は間違ってはいない。しかし keep_alive に限って言えば、死因を問わず再起動するための関数なのだから、完全に期待通りに動く。というか動いてしまう。だからここで例として挙げるには相応しくないと言える（実際に実験してみて延々悩み続けた初心者がここに一人）。</p>
<p>続く。</p>
<p>※　spawn と register の間で競合が発生しなかった場合に限る。もしこの競合が発生した場合、 register の badargエラーで実行が停止する。詳しくは次回「問題点4」を参照。</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/192/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Erlangと外部Rubyプログラムの連携</title>
		<link>http://wp.serpere.info/archives/180</link>
		<comments>http://wp.serpere.info/archives/180#comments</comments>
		<pubDate>Tue, 27 Jan 2009 14:56:04 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=180</guid>
		<description><![CDATA[『プログラムErlang』12章、Cの代わりにRubyで書いてみた。極力ベタな移植を心がけたが、随所にRubyらしさを漂わせたつもり。 example1_driver.rb require './example1' require './example1_comm' &#160; def main&#40;&#41; begin loop do fun, *args = read_cmd&#40;&#41; &#160; result = case fun when 1 twice&#40;args&#91;0&#93;&#41; when 2 sum&#40;args&#91;0&#93;, args&#91;1&#93;&#41; end &#160; write_cmd&#40;&#91;result&#93;&#41; if result end rescue STDERR.puts&#40;&#34;finishied&#34;&#41; exit end end &#160; main&#40;&#41; example1_comm.rb def read_cmd&#40;&#41; len = read_exact&#40;2&#41;.unpack&#40;'n'&#41;.first read_exact&#40;len&#41;.unpack&#40;'C*'&#41; end &#160; def write_cmd&#40;cmds&#41; bin = &#40;&#91;cmds.size&#93; [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F180%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Erlang%E3%81%A8%E5%A4%96%E9%83%A8Ruby%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E9%80%A3%E6%90%BA%22%20%7D);"></div>
<p>『プログラムErlang』12章、Cの代わりにRubyで書いてみた。極力ベタな移植を心がけたが、随所にRubyらしさを漂わせたつもり。</p>
<p>example1_driver.rb</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./example1'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./example1_comm'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> main<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">begin</span>
    <span style="color:#CC0066; font-weight:bold;">loop</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      fun, <span style="color:#006600; font-weight:bold;">*</span>args = read_cmd<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
      result = <span style="color:#9966CC; font-weight:bold;">case</span> fun
               <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">1</span>
                 twice<span style="color:#006600; font-weight:bold;">&#40;</span>args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
               <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">2</span>
                 sum<span style="color:#006600; font-weight:bold;">&#40;</span>args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>, args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
               <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      write_cmd<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>result<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> result
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    STDERR.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;finishied&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">exit</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
main<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>



<p>example1_comm.rb</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> read_cmd<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  len = read_exact<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">unpack</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'n'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>
  read_exact<span style="color:#006600; font-weight:bold;">&#40;</span>len<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">unpack</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'C*'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> write_cmd<span style="color:#006600; font-weight:bold;">&#40;</span>cmds<span style="color:#006600; font-weight:bold;">&#41;</span>
  bin = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>cmds.<span style="color:#9900CC;">size</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> cmds<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">pack</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'nC*'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  write_exact<span style="color:#006600; font-weight:bold;">&#40;</span>bin, bin.<span style="color:#9900CC;">size</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> read_exact<span style="color:#006600; font-weight:bold;">&#40;</span>len<span style="color:#006600; font-weight:bold;">&#41;</span>
  str = <span style="color:#996600;">&quot;&quot;</span>
  str <span style="color:#006600; font-weight:bold;">+</span>= STDIN.<span style="color:#9900CC;">sysread</span><span style="color:#006600; font-weight:bold;">&#40;</span>len<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">while</span> str.<span style="color:#9900CC;">size</span> <span style="color:#006600; font-weight:bold;">&lt;</span> len
  str
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> write_exact<span style="color:#006600; font-weight:bold;">&#40;</span>bin, len<span style="color:#006600; font-weight:bold;">&#41;</span>
  wrote = <span style="color:#006666;">0</span>
  wrote <span style="color:#006600; font-weight:bold;">+</span>= STDOUT.<span style="color:#9900CC;">syswrite</span><span style="color:#006600; font-weight:bold;">&#40;</span>bin<span style="color:#006600; font-weight:bold;">&#91;</span>wrote...<span style="color:#9900CC;">len</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">while</span> wrote <span style="color:#006600; font-weight:bold;">&lt;</span> len
  wrote
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>



<p>example1.rbはそのまんまなので省略。</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/180/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IRC Lite演習の実装</title>
		<link>http://wp.serpere.info/archives/155</link>
		<comments>http://wp.serpere.info/archives/155#comments</comments>
		<pubDate>Sat, 24 Jan 2009 12:59:28 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[『プログラミングErlang』]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=155</guid>
		<description><![CDATA[『プログラミングErlang』11.7に載っている演習の実演。サーバをVMware上のUbuntuで動かし、ホスト側のMac OS Xと合わせて計6つのクライアント・ウィンドウを開いている。グループは2つあり、「Miki」というユーザは両方のグループに（それぞれ別のクライアントとして）ログインしている。 グループの全員の名前を表示するコードを追加してみよう → gsのlistboxオブジェクトを使用して実装した すべてのグループの一覧を表示するコードを追加してみよう → 同じくgsのlistboxを使用して実装した 1対1の会話を追加してみよう → メンバー一覧の中からユーザ名を選んでメッセージ送信を行うと、そのユーザに対してのみメッセージが届くようにした（スクリーンショット中「765pro」グループの「Haruka」と「Miki」のやり取り）。また自分を選ぶと自分にだけ表示されるようにした（「Yukiho」のメッセージ） グループコントローラをサーバマシンで動かさずに、グループに最初に入ったユーザのところで動かすためのコードを追加してみよう → どうしても理解できなかったので実装しなかった 以下雑感。 chat_serverとchat_groupはPidを管理するために微妙に異なるデータ構造を使っている。これが非常にイケてない。DRY原則に従って、lib_pid_assocというモジュールを作って統合した。例えば要素を取り除くremove関数は以下の通り。 remove&#40;Pid, Assoc&#41; -&#62; remove&#40;Pid, Assoc, &#91;&#93;&#41;. &#160; remove&#40;_, &#91;&#93;, L&#41; -&#62; &#123;&#34;????&#34;, L&#125;; remove&#40;Pid, &#91;&#123;Key, Pid&#125;&#124;T&#93;, L&#41; -&#62; &#123;Key, reverse&#40;L, T&#41;&#125;; remove&#40;Pid, &#91;H&#124;T&#93;, L&#41; -&#62; remove&#40;Pid, T, &#91;H&#124;L&#93;&#41;. gsのlistboxオブジェクトは、一度何かのアイテムを選択してしまうと、マウス操作では非選択状態に戻せなくなるらしい（少なくとも私はその方法を発見できなかった）。さすがに不便なので、Membersラベルをクリックしたら選択を解除するコードを追加しておいた。 loop&#40;W&#41; -&#62; receive %... &#123;gs, label_m, buttonpress, _, _&#125; [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F155%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22IRC%20Lite%E6%BC%94%E7%BF%92%E3%81%AE%E5%AE%9F%E8%A3%85%22%20%7D);"></div>
<p><div id="attachment_156" class="wp-caption alignnone" style="width: 310px"><a href="http://wp.serpere.info/wp-content/uploads/2009/01/chat_test.jpg"><img src="http://wp.serpere.info/wp-content/uploads/2009/01/chat_test-300x140.jpg" alt="チャットサーバとクライアントのテスト" title="chat_test" width="300" height="140" class="size-medium wp-image-156" /></a><p class="wp-caption-text">チャットサーバとクライアントのテスト</p></div><br />
『プログラミングErlang』11.7に載っている演習の実演。サーバをVMware上のUbuntuで動かし、ホスト側のMac OS Xと合わせて計6つのクライアント・ウィンドウを開いている。グループは2つあり、「Miki」というユーザは両方のグループに（それぞれ別のクライアントとして）ログインしている。</p>
<dl>
<dt><strong>グループの全員の名前を表示するコードを追加してみよう</strong></dt>
<dd>→ gsのlistboxオブジェクトを使用して実装した</dd>
<dt><strong>すべてのグループの一覧を表示するコードを追加してみよう</strong></dt>
<dd>→ 同じくgsのlistboxを使用して実装した</dd>
<dt><strong>1対1の会話を追加してみよう</strong></dt>
<dd>→ メンバー一覧の中からユーザ名を選んでメッセージ送信を行うと、そのユーザに対してのみメッセージが届くようにした（スクリーンショット中「765pro」グループの「Haruka」と「Miki」のやり取り）。また自分を選ぶと自分にだけ表示されるようにした（「Yukiho」のメッセージ）</dd>
<dt><strong>グループコントローラをサーバマシンで動かさずに、グループに最初に入ったユーザのところで動かすためのコードを追加してみよう</strong></dt>
<dd>→ どうしても理解できなかったので実装しなかった</dd>
</dl>
<p>以下雑感。</p>
<p>chat_serverとchat_groupはPidを管理するために微妙に異なるデータ構造を使っている。これが非常にイケてない。DRY原則に従って、lib_pid_assocというモジュールを作って統合した。例えば要素を取り除くremove関数は以下の通り。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">remove</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Assoc</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">remove</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Assoc</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">remove</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span>   <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#41;</span>             <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#123;</span><span style="color: #ff7800;">&quot;????&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">remove</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pid</span><span style="color: #109ab8;">&#125;</span>|T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">reverse</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">L</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">remove</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">H</span>|T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#41;</span>          <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">remove</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Pid</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">T</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">H</span>|L<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>



<p>gsのlistboxオブジェクトは、一度何かのアイテムを選択してしまうと、マウス操作では非選択状態に戻せなくなるらしい（少なくとも私はその方法を発見できなかった）。さすがに不便なので、Membersラベルをクリックしたら選択を解除するコードを追加しておいた。</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">loop</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #186895;">receive</span>
  <span style="color: #666666; font-style: italic;">%...</span>
        <span style="color: #109ab8;">&#123;</span>gs<span style="color: #6bb810;">,</span> label_m<span style="color: #6bb810;">,</span> buttonpress<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #ff4e18;">gs</span>:<span style="color: #ff3c00;">config</span><span style="color: #109ab8;">&#40;</span>listbox_m<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>selection<span style="color: #6bb810;">,</span> clear<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
            <span style="color: #ff3c00;">loop</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
  <span style="color: #666666; font-style: italic;">%...</span>
  <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>




]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/155/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

