<?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>Shadow &#38; Honnix &#187; Scala</title>
	<atom:link href="http://honnix.com/blog/archives/tag/scala/feed" rel="self" type="application/rss+xml" />
	<link>http://honnix.com/blog</link>
	<description>Two Months</description>
	<lastBuildDate>Wed, 21 Jul 2010 14:09:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>如何在Lift里用javascript的confirm</title>
		<link>http://honnix.com/blog/archives/566</link>
		<comments>http://honnix.com/blog/archives/566#comments</comments>
		<pubDate>Thu, 13 May 2010 15:30:48 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Lift]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[anchor]]></category>
		<category><![CDATA[confirm]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=566</guid>
		<description><![CDATA[使用Lift的SHtml.a()设计ajax调用的时候，老版本的Lift不支持给onclick加入用户自己定义的javascript方法，新版本的有了。 ?View Code SCALA/** * Create an anchor tag around a body which will do an AJAX call and invoke the function * * @param jsFunc -- the user function that will be executed. This function will receive as last parameter * the function that will actually do the ajax call. Hence the user function [...]]]></description>
			<content:encoded><![CDATA[<p>使用Lift的SHtml.a()设计ajax调用的时候，老版本的Lift不支持给onclick加入用户自己定义的javascript方法，新版本的有了。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p566code3'); return false;">View Code</a> SCALA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p5663"><td class="code" id="p566code3"><pre class="scala" style="font-family:monospace;"><span style="color: #00ff00; font-style: italic;">/**
   * Create an anchor tag around a body which will do an AJAX call and invoke the function
   *
   * @param jsFunc -- the user function that will be executed. This function will receive as last parameter
   *                  the function that will actually do the ajax call. Hence the user function can decide when
   * 				  to make the ajax request.
   * @param func - the function to invoke when the link is clicked
   * @param body - the NodeSeq to wrap in the anchor tag
   * @param attrs - the anchor node attributes
   */</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> a<span style="color: #F78811;">&#40;</span>jsFunc<span style="color: #000080;">:</span> Call, func<span style="color: #000080;">:</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;;</span> JsCmd, body<span style="color: #000080;">:</span> NodeSeq, attrs<span style="color: #000080;">:</span> <span style="color: #F78811;">&#40;</span>String, String<span style="color: #F78811;">&#41;</span><span style="color: #000080;">*</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Elem <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span>
    attrs.<span style="color: #000000;">foldLeft</span><span style="color: #F78811;">&#40;</span>fmapFunc<span style="color: #F78811;">&#40;</span>contextFuncBuilder<span style="color: #F78811;">&#40;</span>func<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#40;</span>name <span style="color: #000080;">=&gt;;</span>
            <span style="color: #000080;">&lt;</span>a onclick<span style="color: #000080;">=</span><span style="color: #6666FF;">&quot;{deferCall(Str(name&quot;</span> href<span style="color: #000080;">=</span><span style="color: #6666FF;">&quot;javascript://&quot;</span><span style="color: #000080;">&gt;</span><span style="color: #F78811;">&#123;</span>body<span style="color: #F78811;">&#125;</span><span style="color: #000080;">&lt;</span>/a<span style="color: #000080;">&gt;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span> <span style="color: #000080;">%</span> <span style="color: #000080;">_</span><span style="color: #F78811;">&#41;</span>
  <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>对于jsFunc可以这样理解：<br />
用户定义了一个方法：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p566code4'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p5664"><td class="code" id="p566code4"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #000066; font-weight: bold;">delete</span><span style="color: #009900;">&#40;</span>toDelete<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">confirm</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Delete?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    toDelete<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>那么jsFunc可以这样定义：Call(&#8220;delete&#8221;)，Lift会把它生成的ajax方法作为最后一个参数传递给delete方法。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/566/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>慢慢地转到maven</title>
		<link>http://honnix.com/blog/archives/483</link>
		<comments>http://honnix.com/blog/archives/483#comments</comments>
		<pubDate>Mon, 09 Nov 2009 12:48:16 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[jfetion]]></category>
		<category><![CDATA[libfetion]]></category>
		<category><![CDATA[-d32]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[64位]]></category>
		<category><![CDATA[smsd]]></category>
		<category><![CDATA[Snow Leopard]]></category>
		<category><![CDATA[参数]]></category>
		<category><![CDATA[飞信]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=483</guid>
		<description><![CDATA[开始把之前做的一些项目往maven上转了。先是jfetion，再加上今天做的smsd。 说来惭愧，jfetion做了很久了，但是自己一直都没弄个什么应用出来，一直在用的smsd还是最早的时候用C写的。今天老婆出去逛街，闲来无事，用Scala重写了一遍，已经可以正常工作了，其它的功能慢慢加吧。 基本想法很简单，后台启一个daemon，监视某个文件夹，如果里面有.sms文件，就把里面的内容发送给相应的人，当然必须是飞信上面的好友。 顺便说一下，Snow Leopard的Java默认是64位的，而libfetion没有Mac上64位的版本，所以要么在系统设置里面更改Java的默认设置，要么运行的时候给个参数：java -d32 &#8230;]]></description>
			<content:encoded><![CDATA[<p>开始把之前做的一些项目往maven上转了。先是jfetion，再加上今天做的smsd。</p>
<p>说来惭愧，jfetion做了很久了，但是自己一直都没弄个什么应用出来，一直在用的smsd还是最早的时候用C写的。今天老婆出去逛街，闲来无事，用Scala重写了一遍，已经可以正常工作了，其它的功能慢慢加吧。</p>
<p>基本想法很简单，后台启一个daemon，监视某个文件夹，如果里面有.sms文件，就把里面的内容发送给相应的人，当然必须是飞信上面的好友。</p>
<p>顺便说一下，Snow Leopard的Java默认是64位的，而libfetion没有Mac上64位的版本，所以要么在系统设置里面更改Java的默认设置，要么运行的时候给个参数：java -d32 &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/483/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Scala的XML是只读的</title>
		<link>http://honnix.com/blog/archives/422</link>
		<comments>http://honnix.com/blog/archives/422#comments</comments>
		<pubDate>Fri, 28 Aug 2009 15:40:19 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[BasicTransformer]]></category>
		<category><![CDATA[immutable]]></category>
		<category><![CDATA[RuleTransformer]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=422</guid>
		<description><![CDATA[有什么好处呢？最直接的好处就是同一个node可以被多个xml共享，想想DOM是怎么处理这个的。 问题是一个简单的修改就需要重新建立一个完整的xml。Scala提供了BasictTransformer和RuleTransformer，再加上无敌的case匹配，可以方便地处理某类节点。 有个麻烦地地方，Scala-2.7.5的BasicTransformer有bug，只能用nightly或者等2.8发布了。]]></description>
			<content:encoded><![CDATA[<p>有什么好处呢？最直接的好处就是同一个node可以被多个xml共享，想想DOM是怎么处理这个的。</p>
<p>问题是一个简单的修改就需要重新建立一个完整的xml。Scala提供了BasictTransformer和RuleTransformer，再加上无敌的case匹配，可以方便地处理某类节点。</p>
<p>有个麻烦地地方，Scala-2.7.5的BasicTransformer有bug，只能用nightly或者等2.8发布了。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/422/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala确实非常适合实现DSL</title>
		<link>http://honnix.com/blog/archives/420</link>
		<comments>http://honnix.com/blog/archives/420#comments</comments>
		<pubDate>Sat, 22 Aug 2009 14:17:41 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[dom4j]]></category>
		<category><![CDATA[DSL]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=420</guid>
		<description><![CDATA[用了一上午的时间，就实现了xpath的解释，类似这样的东西：a[@b=="1" and (c/@d==2 or e[f=="abc"])]。再加上Scala对函数对象的支持以及函数名的随意性，很容易就实现了对xml操作的扩展。除了Scala定义好的&#8221;\&#8221;，&#8221;\\&#8221;，加入了&#8221;\%&#8221;来支持复杂的xpath，跟dom4j差不多了。真爽！]]></description>
			<content:encoded><![CDATA[<p>用了一上午的时间，就实现了xpath的解释，类似这样的东西：a[@b=="1" and (c/@d==2 or e[f=="abc"])]。再加上Scala对函数对象的支持以及函数名的随意性，很容易就实现了对xml操作的扩展。除了Scala定义好的&#8221;\&#8221;，&#8221;\\&#8221;，加入了&#8221;\%&#8221;来支持复杂的xpath，跟dom4j差不多了。真爽！</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/420/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala的XML处理非常强大</title>
		<link>http://honnix.com/blog/archives/418</link>
		<comments>http://honnix.com/blog/archives/418#comments</comments>
		<pubDate>Thu, 13 Aug 2009 14:12:52 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=418</guid>
		<description><![CDATA[而且好用。模型非常简单，比该死的DOM好太多了。 Lexer的直接支持使得XML使用起来就像是写代码一样，这样可以直接把XSLT丢掉了。 目前还有些不是很好的地方，比如不能用变量作为tag的名字：&#60;{tag_name}&#62;，这样不行；再比如XPATH的支持还不全。不过好在可以implicit来增加新的方法，语法糖衣真是不错。]]></description>
			<content:encoded><![CDATA[<p>而且好用。模型非常简单，比该死的DOM好太多了。</p>
<p>Lexer的直接支持使得XML使用起来就像是写代码一样，这样可以直接把XSLT丢掉了。</p>
<p>目前还有些不是很好的地方，比如不能用变量作为tag的名字：&lt;{tag_name}&gt;，这样不行；再比如XPATH的支持还不全。不过好在可以implicit来增加新的方法，语法糖衣真是不错。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/418/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我是如何用Scala定义新异常类型的</title>
		<link>http://honnix.com/blog/archives/412</link>
		<comments>http://honnix.com/blog/archives/412#comments</comments>
		<pubDate>Sun, 09 Aug 2009 02:41:30 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[apply]]></category>
		<category><![CDATA[constructor]]></category>
		<category><![CDATA[Exception]]></category>
		<category><![CDATA[extends]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[override]]></category>
		<category><![CDATA[trait]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=412</guid>
		<description><![CDATA[Scala的构造方法非常灵活（具体怎么个灵活法这里不多说了），但随之而来的是重载构造方法的麻烦。 例如定义新异常类型。一般来说，自己定义的异常都属于checked异常，大都从Exception继承过来，所以也大都需要定义多个构造方法。如果用Java来定义，没什么好说的，重载就行，但是用Scala的话就有点麻烦。Scala规定所有重载的构造方法都必须调用或间接调用默认构造方法，所以必须使用如下的方法。 ?View Code SCALAclass MyException&#40;message: String, cause: Throwable&#41; extends Exception&#40;message, cause&#41; &#123; def this&#40;message: String&#41;: = this&#40;message, null&#41; def this&#40;cause: Throwable&#41;: = this&#40;null, cause&#41; def this: = this&#40;null, null&#41; &#125; 当然，这样是可以工作的，但是仔细看看Throwable的实现就会发现如果传入的cause为null话会导致异常栈的丢失。而且最恶心的是Throwable没有提供相应的setter/getter，我们能做的就是调用构造方法。 所以我就想出了下面的怪招。 ?View Code SCALAobject SpcException &#123; def apply&#40;message: String, cause: Throwable&#41;: Exception = &#40;new SpcException1&#40;message, cause&#41;&#41;.asInstanceOf&#91;Exception&#93; &#160; def apply&#40;message: String&#41;: Exception = &#40;new [...]]]></description>
			<content:encoded><![CDATA[<p>Scala的构造方法非常灵活（具体怎么个灵活法这里不多说了），但随之而来的是重载构造方法的麻烦。</p>
<p>例如定义新异常类型。一般来说，自己定义的异常都属于checked异常，大都从Exception继承过来，所以也大都需要定义多个构造方法。如果用Java来定义，没什么好说的，重载就行，但是用Scala的话就有点麻烦。Scala规定所有重载的构造方法都必须调用或间接调用默认构造方法，所以必须使用如下的方法。</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p412code7'); return false;">View Code</a> SCALA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4127"><td class="code" id="p412code7"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> MyException<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>message, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a>, cause<span style="color: #F78811;">&#41;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a>, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span>
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>当然，这样是可以工作的，但是仔细看看Throwable的实现就会发现如果传入的cause为null话会导致异常栈的丢失。而且最恶心的是Throwable没有提供相应的setter/getter，我们能做的就是调用构造方法。<br />
所以我就想出了下面的怪招。</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p412code8'); return false;">View Code</a> SCALA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4128"><td class="code" id="p412code8"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> SpcException <span style="color: #F78811;">&#123;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException1<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException2<span style="color: #F78811;">&#40;</span>message<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException3<span style="color: #F78811;">&#40;</span>cause<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException4<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
<span style="color: #F78811;">&#125;</span>
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">trait</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException1<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException2<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException3<span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>cause<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException4 <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException</pre></td></tr></table></div>

<p>基本思想是定义一个trait，然后定义四种异常，每种都从该trait扩展并提供不同的默认构造方法，同时定义一个singleton，提供四种不同的apply方法用来构造四种不同的异常。这样就可以解决之前的问题，虽然不怎么好看。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/412/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala的Actor机制简要分析</title>
		<link>http://honnix.com/blog/archives/392</link>
		<comments>http://honnix.com/blog/archives/392#comments</comments>
		<pubDate>Mon, 27 Jul 2009 15:49:35 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Actor]]></category>
		<category><![CDATA[react]]></category>
		<category><![CDATA[receive]]></category>
		<category><![CDATA[Thread]]></category>
		<category><![CDATA[线程]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=392</guid>
		<description><![CDATA[Scala里多线程的基础就是Actor，核心思想是用消息传递来进行线程间的信息共享和同步。 Scala的Actor线程模型可以这样理解：所有Actor共享一个线程池，总的线程个数可以配置，也可以根据CPU个数决定；当一个Actor启动之后，Scala分配一个线程给它使用，如果使用receive模型，这个线程就一直为该Actor所有，如果使用react模型，Scala执行完react方法后抛出异常，则该线程就可以被其它Actor使用。 下面看一些核心代码。 ?View Code SCALA1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def start&#40;&#41;: Actor = synchronized &#123; // Reset various flags. // // Note that we do *not* reset `trapExit`. The reason is that // users should be able to set the field [...]]]></description>
			<content:encoded><![CDATA[<p>Scala里多线程的基础就是Actor，核心思想是用消息传递来进行线程间的信息共享和同步。</p>
<p>Scala的Actor线程模型可以这样理解：所有Actor共享一个线程池，总的线程个数可以配置，也可以根据CPU个数决定；当一个Actor启动之后，Scala分配一个线程给它使用，如果使用receive模型，这个线程就一直为该Actor所有，如果使用react模型，Scala执行完react方法后抛出异常，则该线程就可以被其它Actor使用。</p>
<p><span id="more-392"></span></p>
<p>下面看一些核心代码。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p392code13'); return false;">View Code</a> SCALA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39213"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p392code13"><pre class="scala" style="font-family:monospace;">  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> start<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Actor <span style="color: #000080;">=</span> synchronized <span style="color: #F78811;">&#123;</span>
    <span style="color: #008000; font-style: italic;">// Reset various flags.</span>
    <span style="color: #008000; font-style: italic;">//</span>
    <span style="color: #008000; font-style: italic;">// Note that we do *not* reset `trapExit`. The reason is that</span>
    <span style="color: #008000; font-style: italic;">// users should be able to set the field in the constructor</span>
    <span style="color: #008000; font-style: italic;">// and before `act` is called.</span>
&nbsp;
    exitReason <span style="color: #000080;">=</span> <span style="color: #6666FF;">'normal
    exiting = false
    shouldExit = false
&nbsp;
    scheduler execute {
      ActorGC.newActor(Actor.this)
      (new Reaction(Actor.this)).run()
    }
&nbsp;
    this
  }</span></pre></td></tr></table></div>

<p>其中Reaction实现Runnable接口，scheduler基本相当于是一个线程池，所以调用start方法之后会有一个线程来为该Actor服务。</p>
<p>使用receive模型。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p392code14'); return false;">View Code</a> SCALA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39214"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p392code14"><pre class="scala" style="font-family:monospace;">  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> receive<span style="color: #F78811;">&#91;</span>R<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>f<span style="color: #000080;">:</span> PartialFunction<span style="color: #F78811;">&#91;</span>Any, R<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> R <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span>
    assert<span style="color: #F78811;">&#40;</span>Actor.<span style="color: #000000;">self</span> <span style="color: #000080;">==</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a>, <span style="color: #6666FF;">&quot;receive from channel belonging to other actor&quot;</span><span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a>.<span style="color: #000000;">synchronized</span> <span style="color: #F78811;">&#123;</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>shouldExit<span style="color: #F78811;">&#41;</span> exit<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #008000; font-style: italic;">// links</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> qel <span style="color: #000080;">=</span> mailbox.<span style="color: #000000;">extractFirst</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span>m<span style="color: #000080;">:</span> Any<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&amp;</span>gt<span style="color: #000080;">;</span> f.<span style="color: #000000;">isDefinedAt</span><span style="color: #F78811;">&#40;</span>m<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a> eq qel<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
        waitingFor <span style="color: #000080;">=</span> f.<span style="color: #000000;">isDefinedAt</span>
        isSuspended <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">true</span></a>
        suspendActor<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span>
      <span style="color: #F78811;">&#125;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> <span style="color: #F78811;">&#123;</span>
        received <span style="color: #000080;">=</span> Some<span style="color: #F78811;">&#40;</span>qel.<span style="color: #000000;">msg</span><span style="color: #F78811;">&#41;</span>
        sessions <span style="color: #000080;">=</span> qel.<span style="color: #000000;">session</span> <span style="color: #000080;">::</span> sessions
      <span style="color: #F78811;">&#125;</span>
      waitingFor <span style="color: #000080;">=</span> waitingForNone
      isSuspended <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">false</span></a>
    <span style="color: #F78811;">&#125;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> result <span style="color: #000080;">=</span> f<span style="color: #F78811;">&#40;</span>received.<span style="color: #000000;">get</span><span style="color: #F78811;">&#41;</span>
    sessions <span style="color: #000080;">=</span> sessions.<span style="color: #000000;">tail</span>
    result
  <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>如果当前mailbox里面没有可以处理的消息，调用suspendActor，该方法会调用wait；如果有消息，这调用PartialFunction进行处理。</p>
<p>使用react模型。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p392code15'); return false;">View Code</a> SCALA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39215"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code" id="p392code15"><pre class="scala" style="font-family:monospace;">  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> react<span style="color: #F78811;">&#40;</span>f<span style="color: #000080;">:</span> PartialFunction<span style="color: #F78811;">&#91;</span>Any, Unit<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Nothing <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span>
    assert<span style="color: #F78811;">&#40;</span>Actor.<span style="color: #000000;">self</span> <span style="color: #000080;">==</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a>, <span style="color: #6666FF;">&quot;react on channel belonging to other actor&quot;</span><span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a>.<span style="color: #000000;">synchronized</span> <span style="color: #F78811;">&#123;</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>shouldExit<span style="color: #F78811;">&#41;</span> exit<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #008000; font-style: italic;">// links</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> qel <span style="color: #000080;">=</span> mailbox.<span style="color: #000000;">extractFirst</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span>m<span style="color: #000080;">:</span> Any<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&amp;</span>gt<span style="color: #000080;">;</span> f.<span style="color: #000000;">isDefinedAt</span><span style="color: #F78811;">&#40;</span>m<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a> eq qel<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
        waitingFor <span style="color: #000080;">=</span> f.<span style="color: #000000;">isDefinedAt</span>
        continuation <span style="color: #000080;">=</span> f
        isDetached <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">true</span></a>
      <span style="color: #F78811;">&#125;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> <span style="color: #F78811;">&#123;</span>
        sessions <span style="color: #000080;">=</span> List<span style="color: #F78811;">&#40;</span>qel.<span style="color: #000000;">session</span><span style="color: #F78811;">&#41;</span>
        scheduleActor<span style="color: #F78811;">&#40;</span>f, qel.<span style="color: #000000;">msg</span><span style="color: #F78811;">&#41;</span>
      <span style="color: #F78811;">&#125;</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">throw</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SuspendActorException
    <span style="color: #F78811;">&#125;</span>
  <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>如果当前mailbox没有可以处理的消息，设置waitingFor和continuation，这两个变量会在接收到消息的时候使用；如果有消息，则调用scheduleActor，该方法会在线程池里选择一个新的线程来处理，具体的处理方法也是由PartialFunction决定。不管是哪条路径，react都会立即返回，或者说是立即抛出异常，结束该线程的执行，这样该线程就可以被其它Actor使用。</p>
<p>再来看看接收消息的处理代码。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p392code16'); return false;">View Code</a> SCALA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39216"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code" id="p392code16"><pre class="scala" style="font-family:monospace;">  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> send<span style="color: #F78811;">&#40;</span>msg<span style="color: #000080;">:</span> Any, replyTo<span style="color: #000080;">:</span> OutputChannel<span style="color: #F78811;">&#91;</span>Any<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> synchronized <span style="color: #F78811;">&#123;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>waitingFor<span style="color: #F78811;">&#40;</span>msg<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
      received <span style="color: #000080;">=</span> Some<span style="color: #F78811;">&#40;</span>msg<span style="color: #F78811;">&#41;</span>
&nbsp;
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>isSuspended<span style="color: #F78811;">&#41;</span>
        sessions <span style="color: #000080;">=</span> replyTo <span style="color: #000080;">::</span> sessions
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a>
        sessions <span style="color: #000080;">=</span> List<span style="color: #F78811;">&#40;</span>replyTo<span style="color: #F78811;">&#41;</span>
&nbsp;
      waitingFor <span style="color: #000080;">=</span> waitingForNone
&nbsp;
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">!</span>onTimeout.<span style="color: #000000;">isEmpty</span><span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
        onTimeout.<span style="color: #000000;">get</span>.<span style="color: #000000;">cancel</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span>
        onTimeout <span style="color: #000080;">=</span> None
      <span style="color: #F78811;">&#125;</span>
&nbsp;
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span>isSuspended<span style="color: #F78811;">&#41;</span>
        resumeActor<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span>
      <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> <span style="color: #008000; font-style: italic;">// assert continuation != null</span>
        scheduler.<span style="color: #000000;">execute</span><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> Reaction<span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a>, continuation, msg<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> <span style="color: #F78811;">&#123;</span>
      mailbox.<span style="color: #000000;">append</span><span style="color: #F78811;">&#40;</span>msg, replyTo<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>}<br />
如果当前没有在等待消息或者接收到的消息不能处理，就丢到mailbox里去；相反，则进行消息的处理。这里对于receive模型和react模型就有了分支：如果isSuspended为true，表示是receive模型，并且线程在wait，就调用resumeActor，该方法会调用notify；否则就是react模型，同样在线程池里选择一个线程进行处理。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/392/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
