<?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>Erlang-China &#187; start</title>
	<atom:link href="http://erlang-china.org/category/start/feed" rel="self" type="application/rss+xml" />
	<link>http://erlang-china.org</link>
	<description>erlang 中文社区</description>
	<lastBuildDate>Thu, 21 Apr 2011 10:01:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>实战MochiWeb</title>
		<link>http://erlang-china.org/start/mochiweb_intro.html</link>
		<comments>http://erlang-china.org/start/mochiweb_intro.html#comments</comments>
		<pubDate>Wed, 30 Jan 2008 03:26:59 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
				<category><![CDATA[start]]></category>

		<guid isPermaLink="false">http://erlang-china.org/start/mochiweb_intro.html</guid>
		<description><![CDATA[MochiWeb是mochibot.com的Bob Ippolito贡献的开源项目[在这里有一个介绍它的Slide]。 MochiBot.com 提供 Flash 内容的访问统计和用户跟踪服务（大致上，可以理解为针对 flash 的 google Analytics 服务），他们在 mochiweb 之上构建了一个定制化的 web server ，并通过这个 web server 获取用户的访问数据（在这一点上有点象 Erlana 项目）。可以想象，这个定制的 web server 需要很高的并发支持，精简和牢固的底层架构，以及对于 http 协议的完备支持（乃至对于 socket 的直接操控）。如果可以的话，最好还有更为精简的 API ，易于定制的 URL 扩展方式，以及易于理解的底层框架。幸运的是，这些 mochiweb 都已经提供，而且还是开源的。 需要说明的是，相比 yaws / inets httpd 而言，它的目标并不是 apache 之类的软件，它并不是一个完整的 web server （没有cache等机制，因而也不做任何加速动作），它只是一个实现 web server 的工具包（这也就意味着，它直接通过代码来扩展，你可以在它的基础上做任何事）。正因为此，在“需要定制 Web Server”的情况下，它成为一个非常不错的选择（比如，配置在 enginx 的后面，专门用于动态内容的生成）。在 erlang 的世界里，有几个项目已经开始转而使用 mochiweb [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/mochiweb" target=_blank>MochiWeb</a>是<a href="http://www.mochibot.com/" target=_blank>mochibot.com</a>的<a href="http://bob.pythonmac.org/" target=_blank>Bob Ippolito</a>贡献的开源项目[在<a href="http://undefined.org/c4-1/" target=_blank>这里</a>有一个介绍它的Slide]。</p>
<p>MochiBot.com 提供 Flash 内容的访问统计和用户跟踪服务（大致上，可以理解为针对 flash 的 google Analytics 服务），他们在 mochiweb 之上构建了一个定制化的 web server ，并通过这个 web server 获取用户的访问数据（在这一点上有点象 <a href="http://code.google.com/p/erlana/" target=_blank>Erlana</a> 项目）。可以想象，这个定制的 web server 需要很高的并发支持，精简和牢固的底层架构，以及对于 http 协议的完备支持（乃至对于 socket 的直接操控）。如果可以的话，最好还有更为精简的 API ，易于定制的 URL 扩展方式，以及易于理解的底层框架。幸运的是，这些 mochiweb 都已经提供，而且还是开源的。</p>
<p>需要说明的是，相比 yaws / inets httpd 而言，它的目标并不是 apache 之类的软件，它并不是一个完整的 web server （没有cache等机制，因而也不做任何加速动作），它只是一个实现 web server 的工具包（这也就意味着，它直接通过代码来扩展，你可以在它的基础上做任何事）。正因为此，在“需要定制 Web Server”的情况下，它成为一个非常不错的选择（比如，配置在 enginx 的后面，专门用于动态内容的生成）。在 erlang 的世界里，有几个项目已经开始转而使用 mochiweb 。</p>
<p>下面是对这个项目代码的一些粗浅实战。<br />
<span id="more-151"></span><br />
首先遵循它的提示，通过svn获取代码：</p>
<div class="hl-surround"><div class="hl-main">svn checkout http://mochiweb.googlecode.com/svn/trunk/ mochiweb-read-only</div></div>
<p>获得的文件和目录结构如下：</p>
<div class="hl-surround"><div class="hl-main">deps&nbsp; ebin&nbsp; &nbsp; &nbsp;LICENSE&nbsp; &nbsp;priv&nbsp; &nbsp; scripts&nbsp; support<br />doc&nbsp; &nbsp;include&nbsp; Makefile&nbsp; README&nbsp; src</div></div>
<p>注：大写字母开头的是文件，小写字母开头的是目录。这是一个相当标准的 Erlang 项目目录结构，其 Makefile （用到 support 目录的 make 包含文件）非常值得借鉴（而且也有简化这一借鉴步骤的办法，后面会提到）。</p>
<p>这是一个纯粹的 Erlang 项目，并不涉及其它语言写的模块，照老规矩，直接 make ：</p>
<div class="hl-surround"><div class="hl-main">make</div></div>
<p>注：如果你和我一样，仍在 R11* 上工作，那么 make 会在 edoc 的步骤中失败，这是因为 R11* 的 edoc 工具存在 bug 无法正确处理 mochiweb 用到的<a href="http://erlang-china.org/study/parameterized-module.html" target=_blank> Parameterized module 语法</a>，不用管它，并不影响后续使用。</p>
<p>make 完成之后，要怎么试运行呢？这就涉及我们上面提到的“借鉴”工作。因为 mochiweb 是设计用来作为一个完整项目的一个基础部分，也就是说，它只是一个骨架（或者如作者所说的toolkit），在你 make 完之后，什么也干不了，除非你对它进行定制化编码，完成这个 web server 。好在它自己已经提供了工具来简化这一步骤：</p>
<div class="hl-surround"><div class="hl-main">escript scripts/new_mochiweb.erl test</div></div>
<p>new_mochiweb.erl 是一个 EScript 脚本，它负责从 mochiweb 中拷贝使用 mochiweb 所必须文件和目录，形成你的新项目的“骨架”（概念上有点类似于 rails 的自动生成代码）。上面的命令生成了名为 test 的项目，会在当前目录建立名为 test 子目录（还可以使用 escript scripts/new_mochiweb.erl test testdir 将新建立的项目放在 testdir 目录中）。上面的命令生成了一些文件，我加了注释：</p>
<div class="hl-surround"><div class="hl-main">./test/			项目目录<br />&nbsp;&nbsp; &nbsp;Makefile		Make文件<br />&nbsp;&nbsp; &nbsp;start.sh		启动脚本<br />&nbsp;&nbsp; &nbsp;start-dev.sh	开发模式下的启动脚本（开启代码重载机制）<br />./test/ebin/		编译目录<br />./test/support/		Make支持文件目录<br />&nbsp;&nbsp; &nbsp;include.mk		Make包含脚本<br />./test/deps/		依赖目录，包含mochiweb自身<br />./test/src/		代码目录<br />&nbsp;&nbsp; &nbsp;skel.app		实际名称为test.app，OTP规范的应用定义文件<br />&nbsp;&nbsp; &nbsp;Makefile		Make文件<br />&nbsp;&nbsp; &nbsp;skel_web.erl	实际名称为test_web.erl，应用的web服务器代码<br />&nbsp;&nbsp; &nbsp;skel_deps.erl	实际名称为test_deps.erl，负责加载deps目录的代码<br />&nbsp;&nbsp; &nbsp;skel_sup.erl	实际名称为test_sup.erl，OTP规范的监控树<br />&nbsp;&nbsp; &nbsp;skel.hrl		实际名称为test.hrl，应用的头文件<br />&nbsp;&nbsp; &nbsp;skel_app.erl	实际名称为test_app.erl，OTP规范的应用启动文件<br />&nbsp;&nbsp; &nbsp;skel.erl		实际名称为test.erl，应用的API定义文件<br />./test/doc/		文档目录<br />./test/include/		包含文件目录<br />./test/priv/		项目附加目录<br />./test/priv/www/	项目附加的www目录<br />&nbsp;&nbsp; &nbsp;index.html		默认的项目首页</div></div>
<p>是的，什么也不用改，在新生成的项目骨架中，一个可用的web服务器已经就绪：</p>
<div class="hl-surround"><div class="hl-main">make<br />./start-dev.sh</div></div>
<p>这会打开一个 erlang shell ，输出的信息表明在 8000 端口开了一个 web 服务，此时用浏览器访问 http://localhost:8000 （或者其它正确的地址）就能看到“MochiWeb running.”，这表明 mochiweb 配置正确，运行良好。注意，我们上面是用 start-dev.sh 来启动的，它打开了 reloader 特性。</p>
<p>现在修改一下 test_web.erl 的代码，加点料。因为我们上面已经打开了 reloader 所以，不用关掉这个 erlang shell ，我们可以直接修改和编译，然后刷新就能看到效果（有点 PHP 编程的意思了）。把 test_web.erl 改成这样，看看会有什么情况发生：</p>
<div class="hl-title">&#19979;&#36733;: <a href="http://erlang-china.org/wordpress/wp-content/plugins/coolcode/coolcode.php?p=151&amp;download=test_web.erl">test_web.erl</a></div><div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">%% @author author &lt;author@example.com&gt;</span></li>
<li><span style="color: #ffa500;">%% @copyright YYYY author.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">%% @doc Web server for test.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">-</span><span style="color: Blue;">module</span><span style="color: Olive;">(</span><span style="color: Blue;">test_web</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">-</span><span style="color: Blue;">author</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">author &lt;author@example.com&gt;</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">-</span><span style="color: Blue;">export</span><span style="color: Olive;">([</span><span style="color: Blue;">start</span><span style="color: Gray;">/</span><span style="color: Maroon;">1</span><span style="color: Gray;">, </span><span style="color: Blue;">stop</span><span style="color: Gray;">/</span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Blue;">loop</span><span style="color: Gray;">/</span><span style="color: Maroon;">2</span><span style="color: Olive;">])</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">%% External API</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">start</span><span style="color: Olive;">(</span><span style="color: Blue;">Options</span><span style="color: Olive;">)</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; {</span><span style="color: Blue;">DocRoot</span><span style="color: Gray;">, </span><span style="color: Blue;">Options1</span><span style="color: Gray;">} = </span><span style="color: Blue;">get_option</span><span style="color: Olive;">(</span><span style="color: Blue;">docroot</span><span style="color: Gray;">, </span><span style="color: Blue;">Options</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">Loop</span><span style="color: Gray;"> = </span><span style="color: Green;">fun</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">Req</span><span style="color: Olive;">)</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">MODULE</span><span style="color: Gray;">:</span><span style="color: Blue;">loop</span><span style="color: Olive;">(</span><span style="color: Blue;">Req</span><span style="color: Gray;">, </span><span style="color: Blue;">DocRoot</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Green;">end</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">mochiweb_http</span><span style="color: Gray;">:</span><span style="color: Blue;">start</span><span style="color: Olive;">([</span><span style="color: Gray;">{</span><span style="color: Blue;">name</span><span style="color: Gray;">, ?</span><span style="color: Blue;">MODULE</span><span style="color: Gray;">}, {</span><span style="color: Blue;">loop</span><span style="color: Gray;">, </span><span style="color: Blue;">Loop</span><span style="color: Gray;">} | </span><span style="color: Blue;">Options1</span><span style="color: Olive;">])</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">stop</span><span style="color: Olive;">()</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">mochiweb_http</span><span style="color: Gray;">:</span><span style="color: Blue;">stop</span><span style="color: Olive;">(</span><span style="color: Gray;">?</span><span style="color: Blue;">MODULE</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">loop</span><span style="color: Olive;">(</span><span style="color: Blue;">Req</span><span style="color: Gray;">, </span><span style="color: Blue;">DocRoot</span><span style="color: Olive;">)</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">/</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> ++ </span><span style="color: Blue;">Path</span><span style="color: Gray;"> = </span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">get</span><span style="color: Olive;">(</span><span style="color: Blue;">path</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">case</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">get</span><span style="color: Olive;">(</span><span style="color: Blue;">method</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">of</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Method</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">when</span><span style="color: Gray;"> </span><span style="color: Blue;">Method</span><span style="color: Gray;"> =:= </span><span style="color: #8b0000;">'</span><span style="color: Red;">GET</span><span style="color: #8b0000;">'</span><span style="color: Gray;">; </span><span style="color: Blue;">Method</span><span style="color: Gray;"> =:= </span><span style="color: #8b0000;">'</span><span style="color: Red;">HEAD</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">case</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Path</span><span style="color: Gray;"> </span><span style="color: Green;">of</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">timer</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> -&gt;&nbsp; &nbsp; </span><span style="color: #ffa500;">%% 新增了 /timer 这个 URL，它是一个 HTTP Chunked 的例子</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Response</span><span style="color: Gray;"> = </span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">ok</span><span style="color: Olive;">(</span><span style="color: Gray;">{</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">text/plain</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Blue;">chunked</span><span style="color: Gray;">}</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">timer</span><span style="color: Olive;">(</span><span style="color: Blue;">Response</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">_</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">serve_file</span><span style="color: Olive;">(</span><span style="color: Blue;">Path</span><span style="color: Gray;">, </span><span style="color: Blue;">DocRoot</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">end</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #8b0000;">'</span><span style="color: Red;">POST</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">case</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Path</span><span style="color: Gray;"> </span><span style="color: Green;">of</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">_</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">not_found</span><span style="color: Olive;">()</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">end</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">_</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">respond</span><span style="color: Olive;">(</span><span style="color: Gray;">{</span><span style="color: Maroon;">501</span><span style="color: Gray;">, </span><span style="color: Olive;">[]</span><span style="color: Gray;">, </span><span style="color: Olive;">[]</span><span style="color: Gray;">}</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">end</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">%% Internal API</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">get_option</span><span style="color: Olive;">(</span><span style="color: Blue;">Option</span><span style="color: Gray;">, </span><span style="color: Blue;">Options</span><span style="color: Olive;">)</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; {</span><span style="color: Blue;">proplists</span><span style="color: Gray;">:</span><span style="color: Blue;">get_value</span><span style="color: Olive;">(</span><span style="color: Blue;">Option</span><span style="color: Gray;">, </span><span style="color: Blue;">Options</span><span style="color: Olive;">)</span><span style="color: Gray;">, </span><span style="color: Blue;">proplists</span><span style="color: Gray;">:</span><span style="color: Blue;">delete</span><span style="color: Olive;">(</span><span style="color: Blue;">Option</span><span style="color: Gray;">, </span><span style="color: Blue;">Options</span><span style="color: Olive;">)</span><span style="color: Gray;">}.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">%% 打印当前时间，间隔一秒，再在已经打开的 http 连接之上，再次打印，这也就是所谓 HTTP长连接/ServerPush 的一种</span></li>
<li><span style="color: Blue;">timer</span><span style="color: Olive;">(</span><span style="color: Blue;">Response</span><span style="color: Olive;">)</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">Response</span><span style="color: Gray;">:</span><span style="color: Blue;">write_chunk</span><span style="color: Olive;">(</span><span style="color: Blue;">io_lib</span><span style="color: Gray;">:</span><span style="color: Blue;">format</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">The time is: ~p~n</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span style="color: Olive;">[</span><span style="color: Blue;">calendar</span><span style="color: Gray;">:</span><span style="color: Blue;">local_time</span><span style="color: Olive;">()]))</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">timer</span><span style="color: Gray;">:</span><span style="color: Blue;">sleep</span><span style="color: Olive;">(</span><span style="color: Maroon;">1000</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">timer</span><span style="color: Olive;">(</span><span style="color: Blue;">Response</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span></li></ol></div>
<p>编译之前，先访问一下 http://localhost:8000/timer ，是“Not found.”。此时，不要中断之前的 erlang shell 而是直接再次 make ：</p>
<div class="hl-surround"><div class="hl-main">make</div></div>
<p>留意到之前打开的 erlang shell 上出现了这么一行：</p>
<div class="hl-surround"><div class="hl-main">1&gt; Reloading test_web ... ok.</div></div>
<p>此时，再次访问 http://localhost:8000/timer （耐心些 HTTP chunked 获得的数据要积累到一定的字节浏览器才会显示），你会发现这是一个不会“下载结束”的页面，不断会有新的内容出现在下面。你也许可以利用这个特性实现传说中的“无刷新聊天室”。</p>
<p>值得留意的是这样的代码：</p>
<div class="hl-surround"><div class="hl-main">...<br />Req:ok({&quot;text/plain&quot;, chunked}),<br />...<br />Req:serve_file(Path, DocRoot)<br />...<br />Response:write_chunk(io_lib:format(&quot;The time is: ~p~n&quot;,<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[calendar:local_time()])),<br />...</div></div>
<p>我们这里是用 Req:ok(&#8230;) 而不是 request:ok(Req, &#8230;) 这在 Erlang 的代码中并不寻常，Req 是一个变量，通常这个变量的值是某个 atom 表明的是一个 module 的名称，但这里的 Req 显然不是这样。它是一个 “module 的实例”，这就是我们前面提到的“<a href="http://erlang-china.org/study/parameterized-module.html" target=_blank> Parameterized module 语法</a>”的实际应用，它不仅意味着某个模块的名称，还意味着(初始化时)传给这个模块的一系列参数，它包装了与一个 request 相关的数据。应该说，这个语法更加简洁易懂。</p>
<p>问题：</p>
<p>1. 如果在此时，并不关闭正在不断“下载页面”的浏览器，在 test_web.erl 中将 timer 的部分注释掉，然后再次 make ，会发生什么？为什么？<br />
2. 找出 Req 在 mochiweb 的哪个模块中被初始化？如何被初始化？它实际上是由哪个模块来实现的？<br />
3. 解释 test_web.erl 的代码结构，各个部分都起什么作用？它是如何服务于每一个请求的？<br />
4. 如何在 test_web.erl 中直接访问 http 连接的 socket ？</p>
<p>（实际上，这个例子只是一个 HTTP Chunked 的例子而已，你并不能依赖于 HTTP Chunked 来实现聊天室，这不是 HTTP Chunked 的问题，而是因为在现实的网络环境下，路由器有可能会自动断开连接时长超过某个值的连接。）</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/start/mochiweb_intro.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[转]Getting Started With Erlang 和 OTP Design Principles 的部分译文</title>
		<link>http://erlang-china.org/start/cn_translate_getting-started-with-erlang_otp-design-principles.html</link>
		<comments>http://erlang-china.org/start/cn_translate_getting-started-with-erlang_otp-design-principles.html#comments</comments>
		<pubDate>Fri, 19 Oct 2007 06:21:41 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
				<category><![CDATA[start]]></category>

		<guid isPermaLink="false">http://erlang-china.org/start/cn_translate_getting-started-with-erlang_otp-design-principles.html</guid>
		<description><![CDATA[原文链接：blog.sun7.cn 有位热心的 Dino Wu 朋友在 http://wiki.51sun.cn/ErlangDoc 上发表了对《Getting Started With Erlang》和 《OTP Design Principles》这两份文档的部分中文翻译。感谢 Dino Wu 付出宝贵的个人时间为 Erlang 中文社区所做的贡献！ Dino Wu 的译文，在http://wiki.51sun.cn/ErlangDoc(介绍文字相当精炼，也值得一读)上提供了PDF版本的译文下载。 [下载地址] [本地镜像] 后续部分会不定期释出，本文也会继续更新相关的链接。]]></description>
			<content:encoded><![CDATA[<p>原文链接：<a href="http://blog.sun7.cn/archives/389" target=_blank>blog.sun7.cn</a></p>
<p>有位热心的 Dino Wu 朋友在 <a href="http://wiki.51sun.cn/ErlangDoc" target=_blank>http://wiki.51sun.cn/ErlangDoc</a> 上发表了对《<a href="http://www.erlang.org/doc/pdf/getting_started.pdf">Getting Started With Erlang</a>》和 《<a href="http://www.erlang.org/doc/pdf/design_principles.pdf">OTP Design Principles</a>》这两份文档的部分中文翻译。感谢 Dino Wu 付出宝贵的个人时间为 Erlang 中文社区所做的贡献！</p>
<p>Dino Wu 的译文，在<a href="http://wiki.51sun.cn/ErlangDoc" target=_blank>http://wiki.51sun.cn/ErlangDoc</a>(介绍文字相当精炼，也值得一读)上提供了PDF版本的译文下载。</p>
<p>[<a href="http://ftp.sun7.cn/pub/linux/docs/erlang/erlang-trans-zh_CN-0.1a4-2.pdf">下载地址</a>] [<a href='http://erlang-china.org/wp-content/uploads/2007/10/erlang-trans-zh_cn-01a4-2.pdf' title='Getting-Started-with-Erlang'>本地镜像</a>]</p>
<p>后续部分会不定期释出，本文也会继续更新相关的链接。</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/start/cn_translate_getting-started-with-erlang_otp-design-principles.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>editplus stx for erlang?</title>
		<link>http://erlang-china.org/start/editplus_stx_for_erlang.html</link>
		<comments>http://erlang-china.org/start/editplus_stx_for_erlang.html#comments</comments>
		<pubDate>Tue, 18 Sep 2007 09:47:15 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
				<category><![CDATA[start]]></category>

		<guid isPermaLink="false">http://erlang-china.org/start/editplus_stx_for_erlang.html</guid>
		<description><![CDATA[看了一下 erlang-china.org 的来源关键词，没想到，一个排名相当靠前的关键词是“editplus erlang”，想想也是，我当初也是费了好大的劲来配置这个东东，这里贡献出来我的editplus 语法高亮文件给大家共产。 回想一下试验过的 erlang 开发环境，陆陆续续的，也有不少了，目前我最满意的 erlang 开发环境（组合）是这样的，哈哈，忍不住拎出来显摆了： windows 2k + colinux + debian + emacs + erlang mode + putty 因为平常工作还是离不开 win（别和我说 xp，在我的破机器上 2k 比 xp 跑得愉快得多了，所以我就“主动降级”了），没办法，太多东西了，实在没法一下子转投 linux 的怀抱，只能虚拟。而 colinux + debian 正好提供了一个近乎 native 运行的 unix 环境，资源占用很小，运行速度很快。平时当个 service 跑着也不吃力。最大的好处是所有的软件包都是原生的 unix 软件，啥也不用改，直接拖下来就用，个人感觉比 cygwin 强多了。一路 apt-get install emacs erlang 装下来就是了。 编程的时候，putty 登上去（当然要配好 public key [...]]]></description>
			<content:encoded><![CDATA[<p>看了一下 erlang-china.org 的来源关键词，没想到，一个排名相当靠前的关键词是“editplus erlang”，想想也是，我当初也是费了好大的劲来配置这个东东，这里贡献出来我的<a href='http://erlang-china.org/wp-content/uploads/2007/09/erlang.zip' title='editplus 的语法高亮文件' target=_blank>editplus 语法高亮文件</a>给大家共产。</p>
<p>回想一下试验过的 erlang 开发环境，陆陆续续的，也有不少了，目前我最满意的 erlang 开发环境（组合）是这样的，哈哈，忍不住拎出来显摆了：</p>
<p>windows 2k + colinux + debian + emacs + erlang mode + putty</p>
<p>因为平常工作还是离不开 win（别和我说 xp，在我的破机器上 2k 比 xp 跑得愉快得多了，所以我就“主动降级”了），没办法，太多东西了，实在没法一下子转投 linux 的怀抱，只能虚拟。而 colinux + debian 正好提供了一个近乎 native 运行的 unix 环境，资源占用很小，运行速度很快。平时当个 service 跑着也不吃力。最大的好处是所有的软件包都是原生的 unix 软件，啥也不用改，直接拖下来就用，个人感觉比 cygwin 强多了。一路 apt-get install emacs erlang 装下来就是了。</p>
<p>编程的时候，putty 登上去（当然要配好 public key 啥的，以节约生命）就可以用 emacs 。在 unix 下，编译，测试，再也不用担心做好的代码换到 unix 环境就跑不起来了。如果要 x 环境，那就装上 vnc： xfce4 + vnc4server + realvnc view4 ，登录进去，效果一流（额外的好处是可以随时关掉窗口，下次登录回到会话，啥也不会丢）。如果你又想念 eclipse 的 erlide 了，那也没关系，随时在 win 下跑起来便是，apt-get 一个 cvs 回来装上，代码同步就解决了。</p>
<p>现在的烦恼是 emacs 还没习惯，渐渐找感觉中。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/start/editplus_stx_for_erlang.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Unit Test in Erlang</title>
		<link>http://erlang-china.org/start/unit_test_in_erlang.html</link>
		<comments>http://erlang-china.org/start/unit_test_in_erlang.html#comments</comments>
		<pubDate>Thu, 13 Sep 2007 18:25:47 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
				<category><![CDATA[start]]></category>

		<guid isPermaLink="false">http://erlang-china.org/start/unit_test_in_erlang.html</guid>
		<description><![CDATA[Erlang被称作是“工业级的语言”，在测试领域，理应是有相当成熟度的。而，Joe老先生本人，也是崇尚“拿测试结果说话”的人（在《Programming Erlang》书中，上来就搞测试，然后再开讲的例子比比皆是）。就连 Erlang/OTP 本身的代码质量也是有严密的测试作为保障的。所以，如果在Erlang领域，你见到远比其他语言为多的测试相关工具、框架、包，丝毫也不应该感到惊奇。下面，我们就来看看“Erlang的测试兵器谱”中，都有什么好家伙。 首先是大名鼎鼎的 Test_Server ，需要说明的是 Erlang/OTP 自身代码的几千个 Test Case 就是构建在它的基础之上。Test_Server 的功能可谓面面俱到，让人眼花缭乱，从简单的测试任务，到对多环境下的测试，乃至对嵌入式系统进行测试，没有它不在行的。但也正因为此，使用稍嫌复杂，比如必须从 Erlang/OTP 的源码来构建和编译 Test_Server ，又比如较为复杂的 case 定义。 然后是 Yet Another 系列，隆重推出：yatsy——Yet Another Test Server (咦？最后一个 y 是哪里来的呢？)， yatsy 和 test_server 的语法完全一致，功能大致相当，所不同的是： yatsy 是 host 在 google 上的 opensource 的项目，而 test_server 是 ericsson 的产品（虽说也给了 sourcecode 但不是 public repository ，这算哪门子区别？），另一个区别是 yatsy 和 yaws 有很好的结合（都是 Yet [...]]]></description>
			<content:encoded><![CDATA[<p>Erlang被称作是“工业级的语言”，在测试领域，理应是有相当成熟度的。而，Joe老先生本人，也是崇尚“拿测试结果说话”的人（在《Programming Erlang》书中，上来就搞测试，然后再开讲的例子比比皆是）。就连 Erlang/OTP 本身的代码质量也是有严密的测试作为保障的。所以，如果在Erlang领域，你见到远比其他语言为多的测试相关工具、框架、包，丝毫也不应该感到惊奇。下面，我们就来看看“Erlang的测试兵器谱”中，都有什么好家伙。<br />
<span id="more-77"></span><br />
首先是大名鼎鼎的 <a href="http://www.erlang.org/project/test_server/index.html" target=_blank>Test_Server </a>，需要说明的是 Erlang/OTP 自身代码的几千个 Test Case 就是构建在它的基础之上。Test_Server 的功能可谓面面俱到，让人眼花缭乱，从简单的测试任务，到对多环境下的测试，乃至对嵌入式系统进行测试，没有它不在行的。但也正因为此，使用稍嫌复杂，比如必须从 Erlang/OTP 的源码来构建和编译 Test_Server ，又比如较为复杂的 case 定义。</p>
<p>然后是 Yet Another 系列，隆重推出：<a href="http://code.google.com/p/yatsy/" target=_blank>yatsy</a>——Yet Another Test Server (咦？最后一个 y 是哪里来的呢？)， yatsy 和 test_server 的语法完全一致，功能大致相当，所不同的是： yatsy 是 host 在 google 上的 opensource 的项目，而 test_server 是 ericsson 的产品（虽说也给了 sourcecode 但不是 public repository ，这算哪门子区别？），另一个区别是 yatsy 和 yaws 有很好的结合（都是 Yet Another 一家的嘛），主要用来生成 report 。</p>
<p>另外，还有 Erlang QuickCheck 是一个 commercial 的测试工具，咱们支持 opensource 这里就不表了。</p>
<p>我个人最喜欢的小巧工具是 <a href="https://support.process-one.net/doc/display/CONTRIBS/EUnit" target=_blank>EUnit</a> ，简单，易用。对于“非火箭科技”的普通程序员来说，简简单单的就好。60秒入门如下：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Gray;">-</span><span style="color: Blue;">module</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">-</span><span style="color: Blue;">export</span><span style="color: Olive;">([</span><span style="color: Blue;">fib</span><span style="color: Gray;">/</span><span style="color: Maroon;">1</span><span style="color: Olive;">])</span><span style="color: Gray;">.</span></li>
<li><span style="color: #ffa500;">%% 加了这句，会自动多出来一个 test() 方法，测试直接跑 fib:test() 就好了。</span></li>
<li><span style="color: Gray;">-</span><span style="color: Blue;">include_lib</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">eunit/include/eunit.hrl</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> -&gt; </span><span style="color: Maroon;">1</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;"> -&gt; </span><span style="color: Maroon;">1</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Blue;">N</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">when</span><span style="color: Gray;"> </span><span style="color: Blue;">N</span><span style="color: Gray;"> &gt; </span><span style="color: Maroon;">1</span><span style="color: Gray;"> -&gt; </span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Blue;">N</span><span style="color: Gray;">-</span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;"> + </span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Blue;">N</span><span style="color: Gray;">-</span><span style="color: Maroon;">2</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">%% xxx_test() 是测试 case ，test() 会调用每一个 case 就像 junit 一样</span></li>
<li><span style="color: Blue;">fib_test</span><span style="color: Olive;">()</span><span style="color: Gray;"> -&gt; </span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">1.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">%% xxxx_test_() case 生成器，每个 ?_assert(...) 都会生成一个 case 函数</span></li>
<li><span style="color: #ffa500;">%% 一般用这个就可以了</span></li>
<li><span style="color: Blue;">fib_test_</span><span style="color: Olive;">()</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">[</span><span style="color: Gray;">?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">2</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">2</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">3</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">3</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">4</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">5</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">5</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">8</span><span style="color: Olive;">)</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">_assertException</span><span style="color: Olive;">(</span><span style="color: Blue;">error</span><span style="color: Gray;">, </span><span style="color: Blue;">function_clause</span><span style="color: Gray;">, </span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Gray;">-</span><span style="color: Maroon;">1</span><span style="color: Olive;">))</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; ?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Olive;">(</span><span style="color: Maroon;">31</span><span style="color: Olive;">)</span><span style="color: Gray;"> == </span><span style="color: Maroon;">2178309</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">]</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">setup</span><span style="color: Olive;">()</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">io</span><span style="color: Gray;">:</span><span style="color: Blue;">format</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">Setup called</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Olive;">[])</span><span style="color: Gray;">.</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">%% 如果需要 setup 就这么干</span></li>
<li><span style="color: Blue;">do_test_</span><span style="color: Olive;">()</span><span style="color: Gray;"> -&gt;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; {</span><span style="color: Blue;">setup</span><span style="color: Gray;">, </span><span style="color: Green;">fun</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">setup</span><span style="color: Gray;">/</span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Olive;">[</span><span style="color: Gray;">?</span><span style="color: Blue;">_assert</span><span style="color: Olive;">(</span><span style="color: Maroon;">1</span><span style="color: Gray;">=:=</span><span style="color: Maroon;">0</span><span style="color: Olive;">)]</span><span style="color: Gray;">}.</span></li></ol></div>
<p>就这么多了，简洁明快吧。</p>
<p>上面是功能测试或者说单元测试，那么，在性能测试上，我们有鼎鼎大名和鼎鼎大名的 <a href="http://www.process-one.net/en/tsung/" target=_blank>Tsung</a> （嗯，谁知道这个词的正确发音是怎样的？）。这个东西，留待日后俺学习到了再和大家分享。 <img src='http://erlang-china.org/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/start/unit_test_in_erlang.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>目前支持Erlang语法的开发环境</title>
		<link>http://erlang-china.org/start/erlang-editors.html</link>
		<comments>http://erlang-china.org/start/erlang-editors.html#comments</comments>
		<pubDate>Thu, 12 Apr 2007 07:03:09 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
				<category><![CDATA[start]]></category>

		<guid isPermaLink="false">http://erlang-china.org/misc/%e7%9b%ae%e5%89%8d%e6%94%af%e6%8c%81erlang%e8%af%ad%e6%b3%95%e7%9a%84%e5%bc%80%e5%8f%91%e7%8e%af%e5%a2%83.html</guid>
		<description><![CDATA[看到有人谈及开发环境。ok，我们就来盘点一下目前市面上能够见到的，支持 Erlang 语法的 IDE/Editor ，其中，IDE有： 1 加拿大的 CaoYuan （华人哦）开发的 ErlyBird （for NetBeans） 2 大名鼎鼎的 ErlIDE （for Eclipse） Editor有： 1 Emacs 2 Vim 3 JEdit 目前就知道这么多了，其他人补充下吧。 我现在用的环境是 editplus + erlangconsole 呵呵，谁让我的机器太破呢，连 JEdit 都嫌慢。没办法了，没有语法加亮，没有函数OutLine，慢慢也习惯了，好像也不觉得缺啥。]]></description>
			<content:encoded><![CDATA[<p>看到有人谈及开发环境。ok，我们就来盘点一下目前市面上能够见到的，支持 Erlang 语法的 IDE/Editor ，其中，IDE有：</p>
<blockquote><p>1 加拿大的 <a target="_blank" title="CaoYuan's blog" href="http://blogtrader.net/page/dcaoyuan">CaoYuan</a> （华人哦）开发的 <a target="_blank" title="ErlyBird @ sf" href="http://sourceforge.net/projects/erlybird">ErlyBird</a> （for NetBeans）</p>
<p>2 大名鼎鼎的 <a target="_blank" title="ErlIDE @ sf" href="http://sourceforge.net/projects/erlide">ErlIDE</a> （for Eclipse）</p></blockquote>
<p>Editor有：</p>
<blockquote><p>1 Emacs</p>
<p>2 Vim</p>
<p>3 JEdit</p></blockquote>
<p>目前就知道这么多了，其他人补充下吧。</p>
<p>我现在用的环境是 editplus + erlangconsole 呵呵，谁让我的机器太破呢，连 JEdit 都嫌慢。没办法了，没有语法加亮，没有函数OutLine，慢慢也习惯了，好像也不觉得缺啥。 <img src='http://erlang-china.org/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/start/erlang-editors.html/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Erlang/Yaws超快速安装</title>
		<link>http://erlang-china.org/start/cean-install.html</link>
		<comments>http://erlang-china.org/start/cean-install.html#comments</comments>
		<pubDate>Sat, 07 Apr 2007 08:50:03 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
				<category><![CDATA[start]]></category>

		<guid isPermaLink="false">http://erlang-china.org/?p=27</guid>
		<description><![CDATA[gashero 贡献了一篇 erlang 的“超快速入门”，我也来贡献一篇“erlang超快速安装”，买一送一，附赠yaws，超值惊喜 。 ok，广告 blah 到此结束，口水留到下篇再说，让我们超快速的开始： 在linux平台“从头”安装 erlang-otp 是一个冗长乏味的过程，11.xM 的源代码文件倒还真不算大，安装命令也很常见以及非常简单： ./configure &#8211;prefix make install 虽说只有这两句，可在你输入命令之后(以及之间)，陪伴你的只有漫漫无尽的等待。视机器快慢，20到40分钟不等，实在可以说是一件“居家旅行谋杀生命”的必备药品。 现在好了，我们有了 CEAN ，当当当当……。安装过程于是简化为： wget http://cean.process-one.net/R11B/prod/linux-x86/cean_base.tar.gz tar zxvf cean_base.tar.gz ./start.sh 注意：这个时候，你已经装好了 erlang otp 的基本系统，并直接进入了熟悉的 erl console。 然后是魔法时刻： > cean:install(yaws). hoho，搞定，收工。 btw. 如果你象我一样要在“受限” 环境启动 yaws 那就可以这样： > yaws:start_embedded(&#8220;your/doc&#8221;, [{listen, {0,0,0,0}}], [{logdir, "your/log"}]). &#8230;]]></description>
			<content:encoded><![CDATA[<p>gashero 贡献了一篇 erlang 的“超快速入门”，我也来贡献一篇“erlang超快速安装”，买一送一，附赠yaws，超值惊喜 <img src='http://erlang-china.org/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> 。</p>
<p>ok，广告 blah 到此结束，口水留到下篇再说，让我们超快速的开始：</p>
<p>在linux平台“从头”安装 erlang-otp 是一个冗长乏味的过程，11.xM 的源代码文件倒还真不算大，安装命令也很常见以及非常简单：</p>
<blockquote><p>./configure &#8211;prefix<br />
make install</p></blockquote>
<p>虽说只有这两句，可在你输入命令之后(以及之间)，陪伴你的只有漫漫无尽的等待。视机器快慢，20到40分钟不等，实在可以说是一件“居家旅行谋杀生命”的必备药品。</p>
<p>现在好了，我们有了 <a target="_blank" title="CEAN官方站" href="http://cean.process-one.net/">CEAN</a> ，当当当当……。安装过程于是简化为：</p>
<p><span id="more-27"></span></p>
<blockquote><p>wget http://cean.process-one.net/R11B/prod/linux-x86/cean_base.tar.gz<br />
tar zxvf cean_base.tar.gz<br />
./start.sh</p></blockquote>
<p>注意：这个时候，你已经装好了 erlang otp 的基本系统，并直接进入了熟悉的 erl console。</p>
<p>然后是魔法时刻：</p>
<blockquote><p>> cean:install(yaws).</p></blockquote>
<p>hoho，搞定，收工。</p>
<p>btw. 如果你象我一样要在“受限” 环境启动 yaws 那就可以这样：</p>
<blockquote><p>> yaws:start_embedded(&#8220;your/doc&#8221;, [{listen, {0,0,0,0}}], [{logdir, "your/log"}]).</p></blockquote>
<p>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/start/cean-install.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Erlang超快速入门</title>
		<link>http://erlang-china.org/start/fast-start.html</link>
		<comments>http://erlang-china.org/start/fast-start.html#comments</comments>
		<pubDate>Fri, 06 Apr 2007 08:45:03 +0000</pubDate>
		<dc:creator>gashero</dc:creator>
				<category><![CDATA[start]]></category>

		<guid isPermaLink="false">http://erlang-china.org/?p=26</guid>
		<description><![CDATA[日期:2007-04-06 目录 1 开始使用erlang 2 使用Erlang作为计算器 3 编辑前面的表达式 4 编译你的第一个程序 5 深入了解Erlang 1 开始使用erlang 如果你在unix系统下输入 erl ，或者在Window$系统下双击Erlang的图标，你可以看到一些提示: os prompt > erl Eshell V5.5.4 (abort with ^G) 1> _ 其中 &#8220;>&#8221;提示符意味着系统正在等待输入。 2 使用Erlang作为计算器 1> 213183682167*12937192739173917823. 27579983733990928813319999135233 2> _ 记住每个表达式以英文句号结束 3 编辑前面的表达式 可以使用简单的emacs命令获取前面的表达式。常见的几个如下： Unix键 Win$键 说明 ^P Up 获取前一行(previous) ^N Down 获取下一行(next) ^A Home 到行首 ^E End [...]]]></description>
			<content:encoded><![CDATA[<p>日期:2007-04-06</p>
<p>目录</p>
<ul>
<li>1   开始使用erlang</li>
<li>2   使用Erlang作为计算器</li>
<li>3   编辑前面的表达式</li>
<li>4   编译你的第一个程序</li>
<li>5   深入了解Erlang</li>
</ul>
<p><span id="more-26"></span> <strong>1   开始使用erlang</strong></p>
<p>如果你在unix系统下输入 erl  ，或者在Window$系统下双击Erlang的图标，你可以看到一些提示:</p>
<pre>os prompt > erl
Eshell V5.5.4  (abort with ^G)
1> _</pre>
<p>其中 &#8220;>&#8221;提示符意味着系统正在等待输入。</p>
<p><strong>2   使用Erlang作为计算器</strong></p>
<pre>1> 213183682167*12937192739173917823.
27579983733990928813319999135233
2> _</pre>
<p><em>记住每个表达式以英文句号结束</em></p>
<p><strong>3   编辑前面的表达式</strong></p>
<p>可以使用简单的emacs命令获取前面的表达式。常见的几个如下：</p>
<table border="1">
<thead valign="bottom">
<tr>
<th>Unix键</th>
<th>Win$键</th>
<th>说明</th>
</tr>
<tr>
<td>^P</td>
<td>Up</td>
<td>获取前一行(previous)</td>
</tr>
<tr>
<td>^N</td>
<td>Down</td>
<td>获取下一行(next)</td>
</tr>
<tr>
<td>^A</td>
<td>Home</td>
<td>到行首</td>
</tr>
<tr>
<td>^E</td>
<td>End</td>
<td>到行尾</td>
</tr>
<tr>
<td>^D</td>
<td>Del</td>
<td>删除光标前字符</td>
</tr>
<tr>
<td>^F</td>
<td>Left</td>
<td>向前移动一个字符</td>
</tr>
<tr>
<td>^B</td>
<td>Right</td>
<td>向后移动一个字符</td>
</tr>
<tr>
<td>Return</td>
<td>Enter</td>
<td>执行当前命令</td>
</tr>
</table>
<p><em>注意：^X意味着Control+X 。</em></p>
<p>尝试按下Control+P来查看结果。</p>
<p>译者注：一位朋友提示如上的快捷键是在unix系统之下的，Window$下的快捷键附在了如上列表后的括号内。另外，在Unix系统下使用Control+G的退出方式，在Window$下使用Control+C来退出。</p>
<p><strong>4   编译你的第一个程序</strong></p>
<p>把如下内容输入到一个文件里:</p>
<pre>-module(test).
-export([fac/1]).

fac(0) -> 1;
fac(N) -> N * fac(N-1).</pre>
<p>把这些存储到文件 <strong>test.erl</strong> 中，文件名必须与模块名相同。</p>
<p>编译这个程序使用如下命令，并且运行:</p>
<pre>3> c(test).
{ok,test}
4> test:fac(20).
2432902008176640000
5> test:fac(40).
815915283247897734345611269596115894272000000000
6> _</pre>
<p>现在可以做些其他有趣的事情了。</p>
<p><strong>5   深入了解Erlang</strong></p>
<p><strong /> <a href="http://erlang.se/doc/doc-5.4/doc/getting_started/part_frame.html">Getting  Started</a></p>
<p><a href="http://erlang.se/doc/doc-5.4/doc/index.html">Warp me  to the documentation &#8211; I want to read it all</a></p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/start/fast-start.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

