<?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>red_world</title>
	<atom:link href="http://redworld.blog.ubuntu.org.cn/feed/" rel="self" type="application/rss+xml" />
	<link>http://redworld.blog.ubuntu.org.cn</link>
	<description>My world is red~, Linux, Ruby, D, Java, Agile, XP, Scrum......</description>
	<lastBuildDate>Fri, 22 Aug 2008 01:35:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Blog已搬迁</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/08/22/blog%e5%b7%b2%e6%90%ac%e8%bf%81/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/08/22/blog%e5%b7%b2%e6%90%ac%e8%bf%81/#comments</comments>
		<pubDate>Fri, 22 Aug 2008 01:35:45 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/08/22/blog%e5%b7%b2%e6%90%ac%e8%bf%81/</guid>
		<description><![CDATA[新Blog地址：chenk85.com
Feed 输出：http://feeds.feedburner.com/red_world
]]></description>
			<content:encoded><![CDATA[<p>新Blog地址：chenk85.com</p>
<p>Feed 输出：http://feeds.feedburner.com/red_world</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/08/22/blog%e5%b7%b2%e6%90%ac%e8%bf%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>a few interesting rails plugin</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/08/06/a-few-interesting-rails-plugin/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/08/06/a-few-interesting-rails-plugin/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 14:43:02 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/08/06/a-few-rails-plugin-project/</guid>
		<description><![CDATA[最近开发中遇到一些有趣的rails pulgin，好像国内连介绍都没有，所以打算写写。
Rails Widgets
http://www.seesaw.it/en/toolbox/widgets/
一个DSLful的Page widgets plugin，让你简单地在页面上添加各种widgets，如tab，nav等，这些似乎是现在页面上不可或缺的页面元素。这个框架旨在减少手工维护这些widgets的代价，手工维护的话，so buggy！
具体看其演示文档可以看到它是干嘛的。

Bj
http://codeforpeople.rubyforge.org/svn/bj
一个让Rails参与管理Server上后台进程（background job）的plugin。这样有什么好处呢？如果你前台Rails app是使用了后台的某些服务的，那这个插件就非常有用了。
不过这个plugin非常少资料，只能从它的README中获得比较多的信息。
&#8230;&#8230;
]]></description>
			<content:encoded><![CDATA[<p>最近开发中遇到一些有趣的rails pulgin，好像国内连介绍都没有，所以打算写写。</p>
<p><strong>Rails Widgets</strong></p>
<p>http://www.seesaw.it/en/toolbox/widgets/</p>
<p>一个DSLful的Page widgets plugin，让你简单地在页面上添加各种widgets，如tab，nav等，这些似乎是现在页面上不可或缺的页面元素。这个框架旨在减少手工维护这些widgets的代价，手工维护的话，so buggy！</p>
<p>具体看<a href="http://www.slideshare.net/paolo.dona/rails-widgets-by-paolo-dona-at-railstoitaly">其演示文档</a>可以看到它是干嘛的。</p>
<hr />
<p><strong>Bj</strong></p>
<p>http://codeforpeople.rubyforge.org/svn/bj</p>
<p>一个让Rails参与管理Server上后台进程（background job）的plugin。这样有什么好处呢？如果你前台Rails app是使用了后台的某些服务的，那这个插件就非常有用了。</p>
<p>不过这个plugin非常少资料，只能从它的<a href="http://codeforpeople.rubyforge.org/svn/bj/trunk/README">README</a>中获得比较多的信息。</p>
<p>&#8230;&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/08/06/a-few-interesting-rails-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get Start Java Network App Dev</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/08/06/get-start-java-network-app-dev/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/08/06/get-start-java-network-app-dev/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 14:26:10 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/08/06/get-start-java-network-app-dev/</guid>
		<description><![CDATA[如果你要开发一个Java的network app，有很多不错的opensource project帮助你开始开发。
比较基础和底层的话可以试试HttpClient，hc.apache.org，按照它官方的教程，六步走。这个框架提供了Http访问的能力，加上Java的multithread能力，虽然效率不及noblocking io那么高但胜在文档资料多。这个一个初学者的好起点。
高级点的就是mina，mina.apache.org，一个高性能高扩展能力的network app框架。基于Java的nio，并发能力得以保证，并在比较高层次进行封装。不过这个东西文档不多是弱点。值得一提的是Logo，so Cool。
当你的network app需要大量的数据处理时，使用hadoop是个不错解决方案，hadoop.apache.org/。这个MapReduce实现，非常著名，不用我废话了:P Hbase是Hadoop的一个子项目，是Bigtable的实现。Hbase有Ruby的客户端，Hbase-ruby。
另hypertable也是一个值得注意的Bigtable实现，hypertable.org。
现在的Network app常常需要有搜索功能，这时就需要Lunece，Solr，Nutch啦。Lunece也是不用介绍的。Solr很多人也熟悉，一个企业级搜索服务器，是Lunece的的扩展，提供了web管理界面等。Netch，一个通用型的Web搜索引擎，其实就一大Crawler，他的存储基于hadoop，原dadoop是其子项目。
以上的项目好像基本上都是Apache的Project，现在的Apache项目都有Wiki了，以前貌似没有，进步了。
这就是我最近开发Crawler遇到的几个Java Framework。
]]></description>
			<content:encoded><![CDATA[<p>如果你要开发一个Java的network app，有很多不错的opensource project帮助你开始开发。</p>
<p>比较基础和底层的话可以试试HttpClient，<a href="http://hc.apache.org">hc.apache.org</a>，按照它官方的教程，六步走。这个框架提供了Http访问的能力，加上Java的multithread能力，虽然效率不及noblocking io那么高但胜在文档资料多。这个一个初学者的好起点。</p>
<p>高级点的就是mina，<a href="http://mina.apache.org">mina.apache.org</a>，一个高性能高扩展能力的network app框架。基于Java的nio，并发能力得以保证，并在比较高层次进行封装。不过这个东西文档不多是弱点。值得一提的是Logo，so Cool。</p>
<p>当你的network app需要大量的数据处理时，使用hadoop是个不错解决方案，<a href="http://hadoop.apache.org">hadoop.apache.org/</a>。这个MapReduce实现，非常著名，不用我废话了:P Hbase是Hadoop的一个子项目，是Bigtable的实现。Hbase有Ruby的客户端，Hbase-ruby。</p>
<p>另hypertable也是一个值得注意的Bigtable实现，<a href="http://www.hypertable.org/">hypertable.org</a>。</p>
<p>现在的Network app常常需要有搜索功能，这时就需要Lunece，Solr，Nutch啦。Lunece也是不用介绍的。Solr很多人也熟悉，一个企业级搜索服务器，是Lunece的的扩展，提供了web管理界面等。Netch，一个通用型的Web搜索引擎，其实就一大Crawler，他的存储基于hadoop，原dadoop是其子项目。</p>
<p>以上的项目好像基本上都是Apache的Project，现在的Apache项目都有Wiki了，以前貌似没有，进步了。</p>
<p>这就是我最近开发Crawler遇到的几个Java Framework。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/08/06/get-start-java-network-app-dev/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>思考着Blog搬家</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/28/%e6%80%9d%e8%80%83%e7%9d%80blog%e6%90%ac%e5%ae%b6/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/28/%e6%80%9d%e8%80%83%e7%9d%80blog%e6%90%ac%e5%ae%b6/#comments</comments>
		<pubDate>Sun, 27 Jul 2008 17:20:50 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[something]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/28/%e6%80%9d%e8%80%83%e7%9d%80blog%e6%90%ac%e5%ae%b6/</guid>
		<description><![CDATA[最近手头有点闲钱，想去注册一个域名和买个空间，放上自己的Blog，Wiki。等完成后就会结束自己的Blog搬家历史，从msn space，到csdn blog，到blogjava，再到ruby-lang.org.cn，现在到这里的blog.ubuntu.org.cn，如果自己没有资源，或者还会再搬。因为随着对Blog的使用时间增加，慢慢会清楚自己的对Blog的需求有什么。如果自己有资源，那很多需求就可以自己实现。
Blog可能会用typo，因为比较好折腾，如果用WP，自己想去改也会很麻烦。wiki，不知道会不会自己开发个，或者用instiki，再写些JavaScript，放在greasemonkey，然后就可以像Google Note那样，一选一点就可以把选中的资料加到wiki中。
不知道有什么比较好的Rails主机介绍。。。
最近真的很忙，每天大量的开发，还有学习着很多新的东西（从同事从网络从书本）。有两篇Blog想写，但是没有时间写，一篇是只写了一个开头的《Ruby GUI开发思考》还有一篇关于开发中的测试的心得和思考。本来还想着7月份，Weblog能过百篇，现在看来。。。
我太懒了:P
]]></description>
			<content:encoded><![CDATA[<p>最近手头有点闲钱，想去注册一个域名和买个空间，放上自己的Blog，Wiki。等完成后就会结束自己的Blog搬家历史，从msn space，到csdn blog，到blogjava，再到ruby-lang.org.cn，现在到这里的blog.ubuntu.org.cn，如果自己没有资源，或者还会再搬。因为随着对Blog的使用时间增加，慢慢会清楚自己的对Blog的需求有什么。如果自己有资源，那很多需求就可以自己实现。</p>
<p>Blog可能会用typo，因为比较好折腾，如果用WP，自己想去改也会很麻烦。wiki，不知道会不会自己开发个，或者用instiki，再写些JavaScript，放在greasemonkey，然后就可以像Google Note那样，一选一点就可以把选中的资料加到wiki中。</p>
<p>不知道有什么比较好的Rails主机介绍。。。</p>
<p>最近真的很忙，每天大量的开发，还有学习着很多新的东西（从同事从网络从书本）。有两篇Blog想写，但是没有时间写，一篇是只写了一个开头的《Ruby GUI开发思考》还有一篇关于开发中的测试的心得和思考。本来还想着7月份，Weblog能过百篇，现在看来。。。</p>
<p>我太懒了:P</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/28/%e6%80%9d%e8%80%83%e7%9d%80blog%e6%90%ac%e5%ae%b6/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>a bug in attachment_fu</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/28/a-bug-in-attachment_fu/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/28/a-bug-in-attachment_fu/#comments</comments>
		<pubDate>Sun, 27 Jul 2008 17:04:42 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/28/a-bug-in-attachment_fu/</guid>
		<description><![CDATA[attachment_fu ，一个Rails插件，帮助你轻松处理文件上传。
最近使用它时遇到一个bug，其中用到了它的s3存储管理，发现如果没有指定缩略的参数时更新会出错，看了一下原来是默认参数nil出的错，当在File#join路径时，会调用每个参数的to_s方法，这样nil.to_s当然就出错了。或许，大家使用s3存储，并使用了attachment_fu时都存的是缩略图，所以没有遇到这个bug吧。这个错误只出现在update时，报的错是type error。
# line 196
def full_filename(thumbnail = nil)
&#160;&#160;File.join(base_path, thumbnail_name_for(thumbnail))
end
我已经fix了这个bug，并ci到attachment_fu在github的repo。
fix s3 no thumbnail update error bug 
mark一篇文章，关于如何在github上ci path：
http://railsontherun.com/2008/3/3/how-to-use-github-and-submit-a-patch
这是我第一次向开源项目提交代码^_^
]]></description>
			<content:encoded><![CDATA[<p>attachment_fu ，一个Rails插件，帮助你轻松处理文件上传。</p>
<p>最近使用它时遇到一个bug，其中用到了它的s3存储管理，发现如果没有指定缩略的参数时更新会出错，看了一下原来是默认参数nil出的错，当在File#join路径时，会调用每个参数的to_s方法，这样nil.to_s当然就出错了。或许，大家使用s3存储，并使用了attachment_fu时都存的是缩略图，所以没有遇到这个bug吧。这个错误只出现在update时，报的错是type error。</p>
<p><code># line 196<br />
def full_filename(thumbnail = nil)<br />
&nbsp;&nbsp;File.join(base_path, thumbnail_name_for(thumbnail))<br />
end</code></p>
<p>我已经fix了这个bug，并ci到attachment_fu在github的repo。</p>
<p><a href="http://github.com/maninred/attachment_fu/commit/0b4a4b12760e3ba537b2eab468f4af49fb7ef5a0">fix s3 no thumbnail update error bug </a></p>
<p>mark一篇文章，关于如何在github上ci path：<br />
<a href="http://railsontherun.com/2008/3/3/how-to-use-github-and-submit-a-patch">http://railsontherun.com/2008/3/3/how-to-use-github-and-submit-a-patch</a></p>
<p>这是我第一次向开源项目提交代码^_^</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/28/a-bug-in-attachment_fu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>about clound computing</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/21/about-clound-computing/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/21/about-clound-computing/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 05:01:57 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[clound computing]]></category>
		<category><![CDATA[假期]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/21/about-clound-computing/</guid>
		<description><![CDATA[Clound computing is so fun.  Lots of times it‘s used in web 2.0 servces, as i know, like Yahoo, Google app, Amazon S3 + EC2, etc. 
MapReduce,Hadoop,Hbase,Bigtable,Skynet,Solr,&#8230;
I need learn more about nutch-solr-hadoop-hbase-weka recently.
I had a kind of holiday in the summer but I couldn&#8217;t really relax. I&#8217;ve been on the go all this month. [...]]]></description>
			<content:encoded><![CDATA[<p>Clound computing is so fun.  Lots of times it‘s used in web 2.0 servces, as i know, like Yahoo, Google app, Amazon S3 + EC2, etc. </p>
<p>MapReduce,Hadoop,Hbase,Bigtable,Skynet,Solr,&#8230;</p>
<p>I need learn more about nutch-solr-hadoop-hbase-weka recently.</p>
<p>I had a kind of holiday in the summer but I couldn&#8217;t really relax. I&#8217;ve been on the go all this month. -_- But  I have learnt much^_^</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/21/about-clound-computing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>第6个学期结束</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/10/_%e7%ac%ac6%e4%b8%aa%e5%ad%a6%e6%9c%9f%e7%bb%93%e6%9d%9f/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/10/_%e7%ac%ac6%e4%b8%aa%e5%ad%a6%e6%9c%9f%e7%bb%93%e6%9d%9f/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 07:53:38 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[something]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/10/%e7%ac%ac6%e4%b8%aa%e5%ad%a6%e6%9c%9f%e7%bb%93%e6%9d%9f/</guid>
		<description><![CDATA[今天考完试拉。大学就剩下一年了，唉呀呀。
下面开始发牢骚。
每次考试完了之后总会觉得考试很假，都是学期初看完了书和相关的东西，比较有兴趣的东西才会去深入研究。但身边大多数人不是这样，一般都是到了最后一周左右时间才开始背书，一般这类同学都会得到比较高的分数。这与老师的出题方向也有关，出题基本都是作业题，就算什么也不会，考试前去背背作业就能拿很高分。记得中央台还报道过学校这里考试前打印店就非常热闹，其实最后一两天打印都是字特别小的“资料”。
中午发现了这个东西挺搞笑：http://www.cnbeta.com/articles/59918.htm
原来做游戏的是比魔鬼还魔鬼，应该去枪毙。其实我一直就认为现在社会上很多奇诡的问题和国人的经济水平，文化水平不高有关。想想小时候家里的电器还不多，就电冰箱电视机，想买本十万个为什么还要和爸妈讲几天。然后忽然到了小学到了中学，再到大学，一时间生活完全变了，物质水平面目全非，精神水平也不敢恭维。这种变化速度国人无法适应。他们说游戏是毒品，他们就是为了赚钱让你玩更长时间，他们还在高楼大厦里，这个逻辑如果放到其它行业其实也是成立的。
还想到一个事情，如果中国不存在盗版软件或者盗版没那么猖獗，计算机会不会不那么流行。在国外来说，现在正常人使用的计算机，应该是软件贵过硬件。
目前国人的所谓家长群体，认为上网就是玩游戏，用电脑就是玩游戏。特别是目前大学生这个群体，很多人买计算机就是买了一部多功能游戏机，目的主要是娱乐。这是个性价比超低的买卖，花五千块去买部计算机打游戏看A片还不如花一千买部psp爽。但大部分人还是买了，用的是家长的血汗钱，就算是家庭经济水平不高的同学也为了面子也会购入计算机，理由是查资料。然后大学宿舍楼就会出现这样的喊声：“XX，建图阿”，“XX，我在X场X桌”，学生会为了娱乐（不单游戏，还有其他），逃课，通宵等等。大学生玩游戏时一般也会有比较多噪音出来，比如我常听见的“你会不会的阿？”，“你们这群傻13/垃圾”，“那么厉害不去打第一名”，“我踢，我踢，看你们还敢打我”&#8230;&#8230;祖国未来的花朵就是这么成长的。
最近sourceforge还给封了。
这个世界太假拉。
发完牢骚，该干嘛干嘛去，END
]]></description>
			<content:encoded><![CDATA[<p>今天考完试拉。大学就剩下一年了，唉呀呀。</p>
<p>下面开始发牢骚。</p>
<p>每次考试完了之后总会觉得考试很假，都是学期初看完了书和相关的东西，比较有兴趣的东西才会去深入研究。但身边大多数人不是这样，一般都是到了最后一周左右时间才开始背书，一般这类同学都会得到比较高的分数。这与老师的出题方向也有关，出题基本都是作业题，就算什么也不会，考试前去背背作业就能拿很高分。记得中央台还报道过学校这里考试前打印店就非常热闹，其实最后一两天打印都是字特别小的“资料”。</p>
<p>中午发现了这个东西挺搞笑：<a href="http://www.cnbeta.com/articles/59918.htm">http://www.cnbeta.com/articles/59918.htm</a></p>
<p>原来做游戏的是比魔鬼还魔鬼，应该去枪毙。其实我一直就认为现在社会上很多奇诡的问题和国人的经济水平，文化水平不高有关。想想小时候家里的电器还不多，就电冰箱电视机，想买本十万个为什么还要和爸妈讲几天。然后忽然到了小学到了中学，再到大学，一时间生活完全变了，物质水平面目全非，精神水平也不敢恭维。这种变化速度国人无法适应。他们说游戏是毒品，他们就是为了赚钱让你玩更长时间，他们还在高楼大厦里，这个逻辑如果放到其它行业其实也是成立的。</p>
<p>还想到一个事情，如果中国不存在盗版软件或者盗版没那么猖獗，计算机会不会不那么流行。在国外来说，现在正常人使用的计算机，应该是软件贵过硬件。</p>
<p>目前国人的所谓家长群体，认为上网就是玩游戏，用电脑就是玩游戏。特别是目前大学生这个群体，很多人买计算机就是买了一部多功能游戏机，目的主要是娱乐。这是个性价比超低的买卖，花五千块去买部计算机打游戏看A片还不如花一千买部psp爽。但大部分人还是买了，用的是家长的血汗钱，就算是家庭经济水平不高的同学也为了面子也会购入计算机，理由是查资料。然后大学宿舍楼就会出现这样的喊声：“XX，建图阿”，“XX，我在X场X桌”，学生会为了娱乐（不单游戏，还有其他），逃课，通宵等等。大学生玩游戏时一般也会有比较多噪音出来，比如我常听见的“你会不会的阿？”，“你们这群傻13/垃圾”，“那么厉害不去打第一名”，“我踢，我踢，看你们还敢打我”&#8230;&#8230;祖国未来的花朵就是这么成长的。</p>
<p>最近sourceforge还给封了。</p>
<p>这个世界太假拉。</p>
<p>发完牢骚，该干嘛干嘛去，END</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/10/_%e7%ac%ac6%e4%b8%aa%e5%ad%a6%e6%9c%9f%e7%bb%93%e6%9d%9f/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>FxRuby初体验Part4</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart4/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart4/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 03:07:06 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[FxRuby]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart4/</guid>
		<description><![CDATA[之前的：FxRuby初体验Part1，Part2，Part3。
到了PictureBook的V0.4了。这个版本算是基本的功能都做足了，包括了加上了相册选择，相册持久化等等。
#album_list_view.rb
require 'fox16'
&#160;
include Fox
&#160;
class AlbumListView &#60; FXList
&#160; attr_reader :album_list
&#160; def initialize(p, opts)
&#160;&#160;&#160; super(p, :opts =&#62; opts)
&#160; end
&#160; def switcher=(sw)
&#160;&#160;&#160; @switcher = sw
&#160; end
&#160;
&#160; def add_album(album)
&#160;&#160;&#160; appendItem(album.title)
&#160;&#160;&#160; AlbumView.new(@switcher, album)
&#160; end
&#160;&#160;&#160;
&#160; def album_list=(albums)
&#160;&#160;&#160; @album_list = albums
&#160;&#160;&#160; @album_list.each_album do &#124;album&#124;
&#160;&#160;&#160;&#160;&#160; add_album(album)
&#160;&#160;&#160; end
&#160; end
end
&#160;&#160;&#160;
#picture_book.rb
$KCODE = "U"
require 'fox16'
require 'yaml'
&#160;&#160;&#160;
include Fox
&#160;&#160;&#160;
require 'album'
require 'album_list'
require 'photo'
require 'photo_view'
require 'album_view'
require 'album_list_view'
&#160;&#160;&#160;
class PictureBook &#60; FXMainWindow
&#160; def initialize(app)
&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>之前的：FxRuby初体验<a href="http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart1/">Part1</a>，<a href="http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart2/">Part2</a>，<a href="http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart3/">Part3</a>。</p>
<p>到了PictureBook的V0.4了。这个版本算是基本的功能都做足了，包括了加上了相册选择，相册持久化等等。</p>
<p><code>#album_list_view.rb<br />
require 'fox16'<br />
&nbsp;<br />
include Fox<br />
&nbsp;<br />
class AlbumListView &lt; FXList<br />
&nbsp; attr_reader :album_list<br />
&nbsp; def initialize(p, opts)<br />
&nbsp;&nbsp;&nbsp; super(p, :opts =&gt; opts)<br />
&nbsp; end<br />
&nbsp; def switcher=(sw)<br />
&nbsp;&nbsp;&nbsp; @switcher = sw<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def add_album(album)<br />
&nbsp;&nbsp;&nbsp; appendItem(album.title)<br />
&nbsp;&nbsp;&nbsp; AlbumView.new(@switcher, album)<br />
&nbsp; end<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp; def album_list=(albums)<br />
&nbsp;&nbsp;&nbsp; @album_list = albums<br />
&nbsp;&nbsp;&nbsp; @album_list.each_album do |album|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_album(album)<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
end<br />
&nbsp;&nbsp;&nbsp;<br />
#picture_book.rb<br />
$KCODE = "U"<br />
require 'fox16'<br />
require 'yaml'<br />
&nbsp;&nbsp;&nbsp;<br />
include Fox<br />
&nbsp;&nbsp;&nbsp;<br />
require 'album'<br />
require 'album_list'<br />
require 'photo'<br />
require 'photo_view'<br />
require 'album_view'<br />
require 'album_list_view'<br />
&nbsp;&nbsp;&nbsp;<br />
class PictureBook &lt; FXMainWindow<br />
&nbsp; def initialize(app)<br />
&nbsp;&nbsp;&nbsp; super(app, "Picture Book" , :width =&gt; 600, :height =&gt; 400)<br />
&nbsp;&nbsp;&nbsp; add_menu_bar<br />
&nbsp;&nbsp;&nbsp; begin<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @album_list = YAML.load_file("picturebook.yml" )<br />
&nbsp;&nbsp;&nbsp; rescue<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @album_list = AlbumList.new<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @album_list.add_album(Album.new("My Photos" ))<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; splitter = FXSplitter.new(self,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :opts =&gt; SPLITTER_HORIZONTAL|LAYOUT_FILL)<br />
&nbsp;&nbsp;&nbsp; @album_list_view = AlbumListView.new(splitter, LAYOUT_FILL)<br />
&nbsp;&nbsp;&nbsp; @switcher = FXSwitcher.new(splitter, :opts =&gt; LAYOUT_FILL)<br />
&nbsp;&nbsp;&nbsp; @switcher.connect(SEL_UPDATE) do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @switcher.current = @album_list_view.currentItem<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; @album_list_view.switcher = @switcher<br />
&nbsp;&nbsp;&nbsp; @album_list_view.album_list = @album_list<br />
&nbsp; end<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp; def create<br />
&nbsp;&nbsp;&nbsp; super<br />
&nbsp;&nbsp;&nbsp; show(PLACEMENT_SCREEN)<br />
&nbsp; end<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; def add_menu_bar<br />
&nbsp;&nbsp;&nbsp; &nbsp; # 创建一个菜单栏的实例<br />
&nbsp;&nbsp;&nbsp; &nbsp; menu_bar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)<br />
&nbsp;&nbsp;&nbsp; &nbsp; # 创建一个菜单栏项<br />
&nbsp;&nbsp;&nbsp; &nbsp; file_menu = FXMenuPane.new(self)<br />
&nbsp;&nbsp;&nbsp; &nbsp; FXMenuTitle.new(menu_bar, "文件" , :popupMenu =&gt; file_menu)<br />
&nbsp;&nbsp;&nbsp; &nbsp; # 下面是一个创建菜单栏项和所关联动作的绑定<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; import_cmd = FXMenuCommand.new(file_menu, "导入..." )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; import_cmd.connect(SEL_COMMAND) do<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dialog = FXFileDialog.new(self, "导入图片" )<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dialog.selectMode = SELECTFILE_MULTIPLE<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dialog.patternList = ["JPEG Images (*.jpg, *.jpeg)" ]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if dialog.execute != 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; import_photos(dialog.filenames)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new_album_command = FXMenuCommand.new(file_menu, "New Album..." )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new_album_command.connect(SEL_COMMAND) do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; album_title = FXInputDialog.getString("My Album" , self, "New Album" , "Name:" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if album_title<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; album = Album.new(album_title)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @album_list.add_album(album)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @album_list_view.add_album(album)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AlbumView.new(@switcher, album)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp; exit_cmd = FXMenuCommand.new(file_menu, "退出" )# 一个简单的退出项<br />
&nbsp;&nbsp;&nbsp;&nbsp; exit_cmd.connect(SEL_COMMAND) do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; store_album_list<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp; def import_photos(filenames)<br />
&nbsp;&nbsp;&nbsp; filenames.each do |filename|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; photo = Photo.new(filename)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; current_album.add_photo(photo)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; current_album_view.add_photo(photo)<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; current_album_view.create<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def current_album_view<br />
&nbsp;&nbsp;&nbsp; @switcher.childAtIndex(@switcher.current)<br />
&nbsp; end<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp; def current_album<br />
&nbsp;&nbsp;&nbsp; current_album_view.album<br />
&nbsp; end<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp; def store_album_list<br />
&nbsp;&nbsp;&nbsp; File.open("picturebook.yml" , "w" ) do |io|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; io.write(YAML.dump(@album_list))<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
&nbsp;<br />
end<br />
&nbsp;<br />
if __FILE__ == $0<br />
&nbsp; FXApp.new do |app|<br />
&nbsp;&nbsp;&nbsp; PictureBook.new(app)<br />
&nbsp;&nbsp;&nbsp; app.create<br />
&nbsp;&nbsp;&nbsp; app.run<br />
&nbsp; end<br />
end</code></p>
<p>剩下的晚上再写。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>FxRuby初体验Part3</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart3/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart3/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 02:51:46 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[FxRuby]]></category>
		<category><![CDATA[GUI]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart3/</guid>
		<description><![CDATA[之前的：FxRuby初体验Part1，Part2。
这个V0.3的PictureBook添加了相册视图，也就是把相片都放到其中。看看下面的代码吧，我把每次都贴上完整的代码，方便大家复制粘帖:-)
#photo.rb
class Photo
&#160; attr_reader :path
&#160; def initialize(path)
&#160;&#160;&#160; @path = path
&#160; end
end
&#160;
#album.rb
class Album
&#160; attr_reader :title
&#160; def initialize(title)
&#160;&#160;&#160; @title = title
&#160;&#160;&#160; @photos = []
&#160; end
&#160; def add_photo(photo)
&#160;&#160;&#160; @photos &#60;&#60; photo
&#160; end
&#160; def each_photo
&#160;&#160;&#160; @photos.each { &#124;photo&#124; yield photo }
&#160; end
end
&#160;
#album_list.rb
class AlbumList
&#160; def initialize
&#160;&#160;&#160; @albums = []
&#160; end
&#160;
&#160; def add_album(album)
&#160;&#160;&#160; @albums &#60;&#60; album
&#160; end
&#160; def remove_album(album)
&#160;&#160;&#160; @albums.delete(album)
&#160; end
&#160; def [...]]]></description>
			<content:encoded><![CDATA[<p>之前的：FxRuby初体验<a href="http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart1/">Part1</a>，<a href="http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart2/">Part2</a>。</p>
<p>这个V0.3的PictureBook添加了相册视图，也就是把相片都放到其中。看看下面的代码吧，我把每次都贴上完整的代码，方便大家复制粘帖:-)</p>
<p><code>#photo.rb<br />
class Photo<br />
&nbsp; attr_reader :path<br />
&nbsp; def initialize(path)<br />
&nbsp;&nbsp;&nbsp; @path = path<br />
&nbsp; end<br />
end<br />
&nbsp;<br />
#album.rb<br />
class Album<br />
&nbsp; attr_reader :title<br />
&nbsp; def initialize(title)<br />
&nbsp;&nbsp;&nbsp; @title = title<br />
&nbsp;&nbsp;&nbsp; @photos = []<br />
&nbsp; end<br />
&nbsp; def add_photo(photo)<br />
&nbsp;&nbsp;&nbsp; @photos &lt;&lt; photo<br />
&nbsp; end<br />
&nbsp; def each_photo<br />
&nbsp;&nbsp;&nbsp; @photos.each { |photo| yield photo }<br />
&nbsp; end<br />
end<br />
&nbsp;<br />
#album_list.rb<br />
class AlbumList<br />
&nbsp; def initialize<br />
&nbsp;&nbsp;&nbsp; @albums = []<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def add_album(album)<br />
&nbsp;&nbsp;&nbsp; @albums &lt;&lt; album<br />
&nbsp; end<br />
&nbsp; def remove_album(album)<br />
&nbsp;&nbsp;&nbsp; @albums.delete(album)<br />
&nbsp; end<br />
&nbsp; def each_album<br />
&nbsp;&nbsp;&nbsp; @albums.each { |album| yield album }<br />
&nbsp; end<br />
end<br />
&nbsp;<br />
#photo_view.rb<br />
class PhotoView &lt; FXImageFrame<br />
&nbsp; MAX_WIDTH = 200<br />
&nbsp; MAX_HEIGHT = 200<br />
&nbsp; def initialize(p, photo)<br />
&nbsp;&nbsp;&nbsp; super(p, nil)<br />
&nbsp;&nbsp;&nbsp; load_image(photo.path)<br />
&nbsp; end<br />
&nbsp; def load_image(path)<br />
&nbsp;&nbsp;&nbsp; File.open(path, "rb" ) do |io|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.image = FXJPGImage.new(app, io.read)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scale_to_thumbnail<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
&nbsp; def scaled_width(width)<br />
&nbsp;&nbsp;&nbsp; [width, MAX_WIDTH].min<br />
&nbsp; end<br />
&nbsp; def scaled_height(height)<br />
&nbsp;&nbsp;&nbsp; [height, MAX_HEIGHT].min<br />
&nbsp; end<br />
&nbsp; def scale_to_thumbnail<br />
&nbsp;&nbsp;&nbsp; aspect_ratio = image.width.to_f/image.height<br />
&nbsp;&nbsp;&nbsp; if image.width &gt; image.height<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image.scale(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scaled_width(image.width),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scaled_width(image.width)/aspect_ratio,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image.scale(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aspect_ratio*scaled_height(image.height),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scaled_height(image.height),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
end<br />
&nbsp;&nbsp;<br />
#album_view.rb<br />
require 'photo_view'<br />
class AlbumView &lt; FXMatrix<br />
&nbsp; attr_reader :album<br />
&nbsp; def initialize(p, album)<br />
&nbsp;&nbsp;&nbsp; super(p, :opts =&gt; LAYOUT_FILL|MATRIX_BY_COLUMNS)<br />
&nbsp;&nbsp;&nbsp; @album = album<br />
&nbsp;&nbsp;&nbsp; @album.each_photo { |photo| add_photo(photo) }<br />
&nbsp; end<br />
&nbsp; def add_photo(photo)<br />
&nbsp;&nbsp;&nbsp; PhotoView.new(self, photo)<br />
&nbsp; end<br />
&nbsp; def layout<br />
&nbsp;&nbsp;&nbsp; self.numColumns = [width/PhotoView::MAX_WIDTH, 1].max<br />
&nbsp;&nbsp;&nbsp; super<br />
&nbsp; end<br />
end<br />
&nbsp;&nbsp;<br />
#picture_book.rb<br />
require 'fox16'<br />
include Fox<br />
require 'album'<br />
require 'album_view'<br />
require 'photo'<br />
class PictureBook &lt; FXMainWindow<br />
&nbsp; def initialize(app)<br />
&nbsp;&nbsp;&nbsp; super(app, "Picture Book" , :width =&gt; 600, :height =&gt; 400)<br />
&nbsp;&nbsp;&nbsp; add_menu_bar<br />
&nbsp;&nbsp;&nbsp; @album = Album.new("My Photos" )<br />
&nbsp;&nbsp;&nbsp; @album_view = AlbumView.new(self, @album)<br />
&nbsp; end<br />
&nbsp; def add_menu_bar<br />
&nbsp;&nbsp;&nbsp; menu_bar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)<br />
&nbsp;&nbsp;&nbsp; file_menu = FXMenuPane.new(self)<br />
&nbsp;&nbsp;&nbsp; FXMenuTitle.new(menu_bar, "File" , :popupMenu =&gt; file_menu)<br />
&nbsp;&nbsp;&nbsp; import_cmd = FXMenuCommand.new(file_menu, "Import..." )<br />
&nbsp;&nbsp;&nbsp; import_cmd.connect(SEL_COMMAND) do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dialog = FXFileDialog.new(self, "Import Photos" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dialog.selectMode = SELECTFILE_MULTIPLE<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dialog.patternList = ["JPEG Images (*.jpg, *.jpeg)" ]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if dialog.execute != 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; import_photos(dialog.filenames)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; exit_cmd = FXMenuCommand.new(file_menu, "Exit" )<br />
&nbsp;&nbsp;&nbsp; exit_cmd.connect(SEL_COMMAND) do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
&nbsp; def import_photos(filenames)<br />
&nbsp;&nbsp;&nbsp; filenames.each do |filename|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; photo = Photo.new(filename)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @album.add_photo(photo)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @album_view.add_photo(photo)<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; @album_view.create<br />
&nbsp; end<br />
&nbsp; def create<br />
&nbsp;&nbsp;&nbsp; super<br />
&nbsp;&nbsp;&nbsp; show(PLACEMENT_SCREEN)<br />
&nbsp; end<br />
end<br />
&nbsp;&nbsp;<br />
if __FILE__ == $0<br />
&nbsp; FXApp.new do |app|<br />
&nbsp;&nbsp;&nbsp; PictureBook.new(app)<br />
&nbsp;&nbsp;&nbsp; app.create<br />
&nbsp;&nbsp;&nbsp; app.run<br />
&nbsp; end<br />
end</code></p>
<p>这里相对于上个版本的改动的地方有，PictureBook增加了菜单栏，增加了一个视图AlbumView，PhotoView实例的创建放在了AlbumView中，PhotoView中增加了图片的缩略图操作。</p>
<p>菜单栏的创建也听挺麻烦的，先创建<a href="http://www.fxruby.org/doc/api/classes/Fox/FXMenuBar.html">FXMenuBar的</a>实例，然后是创建<a href="http://www.fxruby.org/doc/api/classes/Fox/FXMenuTitle.html">FXMenuTitle</a>和<a href="http://www.fxruby.org/doc/api/classes/Fox/FXMenuPane.html">FXMenuPane</a>的实例，FXMenuTitle是FXMenuBar的下级元素，就是菜单栏的每一段，FXMenuPane是FXMenuTitle的弹出菜单。然后要创建<a href="http://www.fxruby.org/doc/api/classes/Fox/FXCommand.html">FXMenuCommand</a>，它是FXMenuPane的下级元素，实例化后就要用connect方法给出的代码块将其绑定到一定的行为上。</p>
<p>File&gt;Importd这个动作是打开一个文件对话框<a href="http://www.fxruby.org/doc/api/classes/Fox/FXDialogBox.html">FXFileDialog</a>让你选择文件，然后用filenames方法获得选择得到的文件的数组。退出的菜单项很简单，就是一个exit方法。</p>
<p>在PhotoView中的图片操作功能是从FXImageFrame继承得到的，这个能力和接口很像RMagic。 AlbumView 是<a href="http://www.fxruby.org/doc/api/classes/Fox/FXMatrix.html">FXMatrix</a>的实例，FXMatrix是一种布局管理器，它以行列的方式来对组件进行布局。好像布局管理器的基类就是<a href="http://www.fxruby.org/doc/api/classes/Fox/FXPacker.html">FXPacker </a>，可以通过重写它的Layout方法来改变布局流。像这里就改变了FXMatrix的行数。</p>
<p>接着书中作者又改了一下，因为FXMatrix不能够在图片太多的情况下全部显示，会产生因为图片过多导致产生很多行，然后让超出主窗体的图片行无法看见，所以作者又对AlbumView换了一个布局管理器。</p>
<p><code>#album_view.rb<br />
require 'photo_view'<br />
class AlbumView &lt; FXScrollWindow<br />
&nbsp; attr_reader :album<br />
&nbsp; def initialize(p, album)<br />
&nbsp;&nbsp;&nbsp; super(p, :opts =&gt; LAYOUT_FILL)<br />
&nbsp;&nbsp;&nbsp; @album = album<br />
&nbsp;&nbsp;&nbsp; FXMatrix.new(self, :opts =&gt; LAYOUT_FILL|MATRIX_BY_COLUMNS)<br />
&nbsp;&nbsp;&nbsp; @album.each_photo { |photo| add_photo(photo) }<br />
&nbsp; end<br />
&nbsp; def layout<br />
&nbsp;&nbsp;&nbsp; contentWindow.numColumns = [width/PhotoView::MAX_WIDTH, 1].max<br />
&nbsp;&nbsp;&nbsp; super<br />
&nbsp; end<br />
&nbsp; def add_photo(photo)<br />
&nbsp;&nbsp;&nbsp; PhotoView.new(contentWindow, photo)<br />
&nbsp; end<br />
end</code></p>
<p><a href="http://www.fxruby.org/doc/api/classes/Fox/FXScrollWindow.html">FXScrollWindow</a>是另一种布局管理器，它只是多了滚动条。其中还是包含了一个FXMatrix。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/02/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FxRuby初体验Part2</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart2/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart2/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 14:40:12 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[FxRuby]]></category>
		<category><![CDATA[GUI]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart2/</guid>
		<description><![CDATA[接上一篇：FxRuby初体验Part1
本书的入门例子是个相册管理的桌面应用，名曰Picture Book。这个例子书中用了5 Chapter（2－6）来讲，基本讲到了常用的Gui组件。
不废话现在来看看代码，下面是第一个版本的Picture Book App：
#photo.rb
class Photo
&#160; attr_reader :path
&#160; def initialize(path)
&#160;&#160;&#160; @path = path
&#160; end
end
&#160;
#album.rb
class Album
&#160; attr_reader :title
&#160; def initialize(title)
&#160;&#160;&#160; @title = title
&#160;&#160;&#160; @photos = []
&#160; end
&#160; def add_photo(photo)
&#160;&#160;&#160; @photos &#60;&#60; photo
&#160; end
&#160; def each_photo
&#160;&#160;&#160; @photos.each { &#124;photo&#124; yield photo }
&#160; end
end
&#160;
#album_list.rb
class AlbumList
&#160; def initialize
&#160;&#160;&#160; @albums = []
&#160; end
&#160;
&#160; def add_album(album)
&#160;&#160;&#160; @albums &#60;&#60; album
&#160; end
&#160; def [...]]]></description>
			<content:encoded><![CDATA[<p>接上一篇：<a href="http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart1/">FxRuby初体验Part1</a></p>
<p>本书的入门例子是个相册管理的桌面应用，名曰Picture Book。这个例子书中用了5 Chapter（2－6）来讲，基本讲到了常用的Gui组件。</p>
<p>不废话现在来看看代码，下面是第一个版本的Picture Book App：</p>
<p><code>#photo.rb<br />
class Photo<br />
&nbsp; attr_reader :path<br />
&nbsp; def initialize(path)<br />
&nbsp;&nbsp;&nbsp; @path = path<br />
&nbsp; end<br />
end<br />
&nbsp;<br />
#album.rb<br />
class Album<br />
&nbsp; attr_reader :title<br />
&nbsp; def initialize(title)<br />
&nbsp;&nbsp;&nbsp; @title = title<br />
&nbsp;&nbsp;&nbsp; @photos = []<br />
&nbsp; end<br />
&nbsp; def add_photo(photo)<br />
&nbsp;&nbsp;&nbsp; @photos &lt;&lt; photo<br />
&nbsp; end<br />
&nbsp; def each_photo<br />
&nbsp;&nbsp;&nbsp; @photos.each { |photo| yield photo }<br />
&nbsp; end<br />
end<br />
&nbsp;<br />
#album_list.rb<br />
class AlbumList<br />
&nbsp; def initialize<br />
&nbsp;&nbsp;&nbsp; @albums = []<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def add_album(album)<br />
&nbsp;&nbsp;&nbsp; @albums &lt;&lt; album<br />
&nbsp; end<br />
&nbsp; def remove_album(album)<br />
&nbsp;&nbsp;&nbsp; @albums.delete(album)<br />
&nbsp; end<br />
&nbsp; def each_album<br />
&nbsp;&nbsp;&nbsp; @albums.each { |album| yield album }<br />
&nbsp; end<br />
end<br />
&nbsp;<br />
#photo_view.rb<br />
class PhotoView &lt; FXImageFrame<br />
&nbsp;&nbsp; def initialize(p, photo)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(p, nil)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; load_image(photo.path)<br />
&nbsp;&nbsp; end<br />
&nbsp;&nbsp; def load_image(path)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File.open(path, "rb" ) do |io|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.image = FXJPGImage.new(app, io.read)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp; end<br />
end<br />
&nbsp;<br />
#picturebook.rb<br />
require 'fox16'<br />
include Fox<br />
require 'photo'<br />
require 'photo_view'<br />
class PictureBook &lt; FXMainWindow<br />
&nbsp; def initialize(app)<br />
&nbsp;&nbsp;&nbsp; super(app, "Picture Book" , :width =&gt; 600, :height =&gt; 400)<br />
&nbsp;&nbsp;&nbsp; photo = Photo.new("shoe.jpg" )<br />
&nbsp;&nbsp;&nbsp; photo_view = PhotoView.new(self, photo)<br />
&nbsp; end<br />
&nbsp; def create<br />
&nbsp;&nbsp;&nbsp; super<br />
&nbsp;&nbsp;&nbsp; show(PLACEMENT_SCREEN)<br />
&nbsp; end<br />
end<br />
if __FILE__ == $0<br />
&nbsp; FXApp.new do |app|<br />
&nbsp;&nbsp;&nbsp; PictureBook.new(app)<br />
&nbsp;&nbsp;&nbsp; app.create<br />
&nbsp;&nbsp;&nbsp; app.run<br />
&nbsp; end<br />
end</code></p>
<p>这是个V0.1的版本。不过你从中看出这个应用写得很MVC。</p>
<p>Model部分就是Photo，Album，AlbumList三个，Controller部分（当然它还没有细化）就是PictureBook，View部分就是PhotoView。就是如此清晰的结构，我想如果是正在学着什么MFC的可怜人儿们看到了之后会把那本什么深入浅出MFC扔了吧。</p>
<p>对比那个HelloWorld，这堆代码除了多了几个普通的Ruby Class（扮演Model的那几个）外，就是多了一个继承自<a href="http://www.fxruby.org/doc/api/classes/Fox/FXImageFrame.html">FXImageFrame</a>的PhotoView，还有在FXMainWindow的构造方法中多了对PhotoView的实例化，实例化时将其自身挂钩到PictureBook（构造方法的第一个参数）。之后在App实例化后会实例化MainWindow，接着实例化MainWindow包含的组件，比如PhotoView这个FxImageFrame。PhotoView中对图片的包装是这样的，它先读入Photo的路径，然后用<a href="http://www.fxruby.org/doc/api/classes/Fox/FXImage.html">FxImage</a>组件对图片进行包装，然后保存为自己的一个实例变量image中。</p>
<p>PictureBook的第一个版本就是这样。</p>
<p>接着下一篇讲下个版本和下下篇讲下下个版本，然后就介绍完了。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FxRuby初体验Part1</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart1/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart1/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 14:14:40 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[FxRuby]]></category>
		<category><![CDATA[GUI]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart1/</guid>
		<description><![CDATA[FxRuby，一个更新较为频繁的Ruby GUI 开发库。今年还出了本书，今晚刚好有空，吃了饭后，6：30开始到现在9：30，看完了它的入门例子。其实是因为今晚不用开工，而想起了一个想做很久的事情，就是开发一个编辑器，一个能够用Ruby作为配置和开发语言的编辑器，就像Emacs能用Lisp在其上开发一样，而且能支持Rails，Rspec，Rake语法和开发辅助（如MVC跳转）等等，这是个妄想:-)

http://pragprog.com/titles/fxruby/fxruby

先来看看它的HelloWorld的代码：
require 'fox16'
include Fox
class HelloWindow &#60; FXMainWindow
&#160; def initialize(app)
&#160;&#160;&#160; super(app, "Hello, World!" , :width =&#62; 200, :height =&#62; 100)
&#160; end
&#160; def create
&#160;&#160;&#160; super
&#160;&#160;&#160; show(PLACEMENT_SCREEN)
&#160; end
end
if __FILE__ == $0
&#160; FXApp.new do &#124;app&#124;
&#160;&#160;&#160; HelloWindow.new(app)
&#160;&#160;&#160; app.create
&#160;&#160;&#160; app.run
&#160; end
end
HW没什么太多好讲的，有些东西要提一提就Ok了。GUI应用，肯定有个明显的入口点，就是FxApp的实例，因为是Desktop app，所以一般都有个主窗体，在FxRuby中是FXMainWindow的实例。FxRuby中，App实例创建之后还要调用create和run两个方法，主窗体的构造函数要做的事情是设置好主窗体的属性，App的create方法会调用会调用每个下级控件的create方法，在create中要加入的就是显示的方式(好像窗体才需要)等等。从上面的HW就可以看到这些。

FxRuby官方手册中还有另一个复杂一点点的HelloWorld。
入门例子是个相册管理的桌面应用，名曰Picture Book。这个例子书中用了5 Chapter（2－6）来讲，基本讲到了常用的Gui组件。
好像太长了，拆开放到另一个日志上吧。
参考Link：
FxRuby官站：http://www.fxruby.org/
FxRuby的Rdoc：http://www.fxruby.org/doc/api/
FxRuby在线手册：http://www.fxruby.org/doc/book.html
]]></description>
			<content:encoded><![CDATA[<p>FxRuby，一个更新较为频繁的Ruby GUI 开发库。今年还出了本书，今晚刚好有空，吃了饭后，6：30开始到现在9：30，看完了它的入门例子。其实是因为今晚不用开工，而想起了一个想做很久的事情，就是开发一个编辑器，一个能够用Ruby作为配置和开发语言的编辑器，就像Emacs能用Lisp在其上开发一样，而且能支持Rails，Rspec，Rake语法和开发辅助（如MVC跳转）等等，这是个妄想:-)</p>
<p><a href="http://pragprog.com/titles/fxruby/fxruby"><img src="http://www.fxruby.org/images/fxruby-book.jpg" alt="FxRuby book" /></a><br />
<a href="http://pragprog.com/titles/fxruby/fxruby">http://pragprog.com/titles/fxruby/fxruby<br />
</a></p>
<p>先来看看它的HelloWorld的代码：<br />
<code>require 'fox16'<br />
include Fox<br />
class HelloWindow &lt; FXMainWindow<br />
&nbsp; def initialize(app)<br />
&nbsp;&nbsp;&nbsp; super(app, "Hello, World!" , :width =&gt; 200, :height =&gt; 100)<br />
&nbsp; end<br />
&nbsp; def create<br />
&nbsp;&nbsp;&nbsp; super<br />
&nbsp;&nbsp;&nbsp; show(PLACEMENT_SCREEN)<br />
&nbsp; end<br />
end<br />
if __FILE__ == $0<br />
&nbsp; FXApp.new do |app|<br />
&nbsp;&nbsp;&nbsp; HelloWindow.new(app)<br />
&nbsp;&nbsp;&nbsp; app.create<br />
&nbsp;&nbsp;&nbsp; app.run<br />
&nbsp; end<br />
end</code></p>
<p>HW没什么太多好讲的，有些东西要提一提就Ok了。GUI应用，肯定有个明显的入口点，就是<a href="http://www.fxruby.org/doc/api/classes/Fox/FXApp.html">FxApp</a>的实例，因为是Desktop app，所以一般都有个主窗体，在FxRuby中是<a href="http://www.fxruby.org/doc/api/classes/Fox/FXMainWindow.html">FXMainWindow</a>的实例。FxRuby中，App实例创建之后还要调用create和run两个方法，主窗体的构造函数要做的事情是设置好主窗体的属性，App的create方法会调用会调用每个下级控件的create方法，在create中要加入的就是显示的方式(好像窗体才需要)等等。从上面的HW就可以看到这些。<br />
<a href="http://www.fxruby.org/doc/ch03s05.html"><br />
FxRuby官方手册</a>中还有另一个复杂一点点的HelloWorld。</p>
<p>入门例子是个相册管理的桌面应用，名曰Picture Book。这个例子书中用了5 Chapter（2－6）来讲，基本讲到了常用的Gui组件。</p>
<p>好像太长了，拆开放到另一个日志上吧。</p>
<p>参考Link：</p>
<p>FxRuby官站：<a href="http://www.fxruby.org/">http://www.fxruby.org/</a></p>
<p>FxRuby的Rdoc：<a href="http://www.fxruby.org/doc/api/">http://www.fxruby.org/doc/api/</a></p>
<p>FxRuby在线手册：<a href="http://www.fxruby.org/doc/book.html">http://www.fxruby.org/doc/book.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/07/01/fxruby%e5%88%9d%e4%bd%93%e9%aa%8cpart1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>有眼不识RoR</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/27/%e6%9c%89%e7%9c%bc%e4%b8%8d%e8%af%86ror/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/27/%e6%9c%89%e7%9c%bc%e4%b8%8d%e8%af%86ror/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 14:55:52 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Thinking]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[大学]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/27/%e6%9c%89%e7%9c%bc%e4%b8%8d%e8%af%86ror/</guid>
		<description><![CDATA[前天，学校的网页设计大赛，展示并且评审。我用的是Ruby on Rails开发一个Web日程管理的应用。结果评委老师们一直认为RoR是一个网站，和他们讲了许久，他们还是认为我和另一个也是用RoR开发的同学是抄袭所谓开源项目的。并且他们对开源项目这种东西，觉得十分的小儿科，觉得很新奇，很Toyful。当我在展示应用中的很多有趣的Ajax效果之后台下同学们还有有些兴趣，但是我看到老师们全部是低下头不听我讲的。虽然最后我获得了一个所谓的最佳代码奖，但是我和同学都不爽，不爽的是自己的作品被人认为是抄袭。更令我失望的是，虽然很多同学看到演示觉得很好玩，但是只有一个学生向我要了联系方式，而且也没有联系我。
今晚看了最新一期的程序员，这一期的主题讲的是开源，很多地方都提到了一点，就是开源要从大学教育开始，让学生在学习的过程中去阅读这些开源的项目，并且去参与其中，甚至去做出贡献。我觉得这个离国内的现实还是好远，国内的大学绝大多数的学生和老师都对开源没什么认识，他们只认得Ms，认得Windows，他们认为VC就是C++，SQL就是SQL Server，认为电脑就是Windows，课件就叫PPT。
我自从发现了Linux下校园网的上网解决方案之后，就再也没有怎么用过windows，并一年前就把windows删除了。其实我也向很多人推广了Linux，但是很多人都是一两天新鲜过后就删除了或者根本没有用过。现在我怎么用IDE，怎么不爽，总觉得写完一个东西之后一定要按下Esc，：，w。
难道中国大地这片土壤真的不适合开源，还是开源只是少数人的游戏？中国人很让我费解。
]]></description>
			<content:encoded><![CDATA[<p>前天，学校的网页设计大赛，展示并且评审。我用的是Ruby on Rails开发一个Web日程管理的应用。结果评委老师们一直认为RoR是一个网站，和他们讲了许久，他们还是认为我和另一个也是用RoR开发的同学是抄袭所谓开源项目的。并且他们对开源项目这种东西，觉得十分的小儿科，觉得很新奇，很Toyful。当我在展示应用中的很多有趣的Ajax效果之后台下同学们还有有些兴趣，但是我看到老师们全部是低下头不听我讲的。虽然最后我获得了一个所谓的最佳代码奖，但是我和同学都不爽，不爽的是自己的作品被人认为是抄袭。更令我失望的是，虽然很多同学看到演示觉得很好玩，但是只有一个学生向我要了联系方式，而且也没有联系我。</p>
<p>今晚看了最新一期的程序员，这一期的主题讲的是开源，很多地方都提到了一点，就是开源要从大学教育开始，让学生在学习的过程中去阅读这些开源的项目，并且去参与其中，甚至去做出贡献。我觉得这个离国内的现实还是好远，国内的大学绝大多数的学生和老师都对开源没什么认识，他们只认得Ms，认得Windows，他们认为VC就是C++，SQL就是SQL Server，认为电脑就是Windows，课件就叫PPT。</p>
<p>我自从发现了Linux下校园网的上网解决方案之后，就再也没有怎么用过windows，并一年前就把windows删除了。其实我也向很多人推广了Linux，但是很多人都是一两天新鲜过后就删除了或者根本没有用过。现在我怎么用IDE，怎么不爽，总觉得写完一个东西之后一定要按下Esc，：，w。</p>
<p>难道中国大地这片土壤真的不适合开源，还是开源只是少数人的游戏？中国人很让我费解。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/27/%e6%9c%89%e7%9c%bc%e4%b8%8d%e8%af%86ror/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>使用Skinny Spec的一个小技巧</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/26/%e4%bd%bf%e7%94%a8skinny-spec%e7%9a%84%e4%b8%80%e4%b8%aa%e5%b0%8f%e6%8a%80%e5%b7%a7/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/26/%e4%bd%bf%e7%94%a8skinny-spec%e7%9a%84%e4%b8%80%e4%b8%aa%e5%b0%8f%e6%8a%80%e5%b7%a7/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 13:34:41 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/26/%e4%bd%bf%e7%94%a8skinny-spec%e7%9a%84%e4%b8%80%e4%b8%aa%e5%b0%8f%e6%8a%80%e5%b7%a7/</guid>
		<description><![CDATA[使用Skinny Spec对Controller进行测试时需要定义shared_request来进行请求，但是这个方法的命名非常的令我费解，一般都是使用do_get，
，make_request，do_request等等，那要使用Skinny_Spec对原来的Spec进行测试时就挺麻烦的拉。
因为我是个懒人，我就加了些代码Hack一下，就不用去定义多个shared_request方法。
#spec/spec_helper.rb
module ControllerMacros
&#160;
&#160; module ExampleMethods
&#160;&#160;&#160; def shared_request
&#160;&#160;&#160;&#160;&#160; verb = [:get, :post, :put, :delete].find{&#124;verb&#124; respond_to? :"do_#{verb}"}
&#160;&#160;&#160;&#160;&#160; raise "未定义do_get, do_post, do_put, 或do_delete方法 / No do_get, do_post_ do_put, or do_delete has been defined" unless verb
&#160;&#160;&#160;&#160;&#160; send("do_#{verb}")
&#160;&#160;&#160; end
&#160; end
end
Spec::Runner.configure do &#124;config&#124;
&#160; #...
&#160; config.include(ControllerMacros, :type =&#62; :controllers)
end
]]></description>
			<content:encoded><![CDATA[<p>使用Skinny Spec对Controller进行测试时需要定义shared_request来进行请求，但是这个方法的命名非常的令我费解，一般都是使用do_get，<br />
，make_request，do_request等等，那要使用Skinny_Spec对原来的Spec进行测试时就挺麻烦的拉。</p>
<p>因为我是个懒人，我就加了些代码Hack一下，就不用去定义多个shared_request方法。</p>
<p><code>#spec/spec_helper.rb<br />
module ControllerMacros<br />
&nbsp;<br />
&nbsp; module ExampleMethods<br />
&nbsp;&nbsp;&nbsp; def shared_request<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; verb = [:get, :post, :put, :delete].find{|verb| respond_to? :"do_#{verb}"}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise "未定义do_get, do_post, do_put, 或do_delete方法 / No do_get, do_post_ do_put, or do_delete has been defined" unless verb<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; send("do_#{verb}")<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
end<br />
Spec::Runner.configure do |config|<br />
&nbsp; #...<br />
&nbsp; config.include(ControllerMacros, :type =&gt; :controllers)<br />
end</code></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/26/%e4%bd%bf%e7%94%a8skinny-spec%e7%9a%84%e4%b8%80%e4%b8%aa%e5%b0%8f%e6%8a%80%e5%b7%a7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rspec测试代码重构</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/23/refactoring_rspec_code/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/23/refactoring_rspec_code/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 05:57:51 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/23/refactoring_rspec_code/</guid>
		<description><![CDATA[消除Spec中的冗余，减少浪费。
看到ben的Blog写了一篇关于Rspec的测试宏的文章：
http://www.benmabey.com/2008/06/08/writing-macros-in-rspec/
其实很多人都是看到Tammer Saleh在MountainWest_Ruby_Conference2008上的Shoulda演示后，和我有一样的感想，就是如果如此DSL化，如此DRY的测试宏能用在Rspec上那就好了。那时我还把Shoulda的官方文档翻译了一下=_=，还有人和我讨论为什么要用Shoulda，还说他就是喜欢Rspec，其实我一次也没有用过Shoulda，但就是觉得这个DSL写的很好。不过Shoulda的缺点也很明显，AR的测试宏依赖于fixture，在业界不提倡使用fixture的情况下还有对测试数据的控制粒度的角度来说，这个做法是不受欢迎的。Rspec中提倡的是全部数据都是在测试时手动Mock出来，所以在1.1.4中才有了stub_mock!这个方法来减轻Mock对象的负担。
Rspec测试的粒度是比较细的，测试的覆盖面在Stroy框架出来之后也能和之前Rails提供的Unittest一样。但是Rspec的测试代码，看上去很冗余，一开始就有这种感觉，一直到看到了Shoulda才发现原来它冗余的地方是什么，这存在于很多地方，比如Controller中每次都是mock一个请求方法，然后就对各种会触发的行为和保存的状态进行断言。这些每次千篇一律的东西，我在想如果在每个context下定义一个请求方法（do_xxx之类的），然后在测试时会在测试方法内部的断言前或断言后自动调用它，这样就能减少很多冗余了。当然我在看完了Shoulda的文档后也尝试写出Rspec的测试宏，不过由于不知道怎么连接到Rspec中就放弃了，话说回来，Rspec中每个测试中上下文关系是很复杂的。
不说废话了，看看鬼佬们怎么减少Rspec中的冗余吧。
下面是一个常见的以Product为领域模型的Controller的测试，用Rspec-Rails插件生成的Scaffold的测试就类似下面这样：
describe ProductsController do
&#160; describe "handling GET /products" do
&#160;
&#160;&#160;&#160; before(:each) do
&#160;&#160;&#160;&#160;&#160; @product = mock_model(Products)
&#160;&#160;&#160;&#160;&#160; Product.stub!(:find).and_return([@product])
&#160;&#160;&#160; end
&#160;
&#160;&#160;&#160; def do_get
&#160;&#160;&#160;&#160;&#160; get :index
&#160;&#160;&#160; end
&#160;
&#160;&#160;&#160; it "should be successful" do
&#160;&#160;&#160;&#160;&#160; do_get
&#160;&#160;&#160;&#160;&#160; response.should be_success
&#160;&#160;&#160; end
&#160;
&#160;&#160;&#160; it "should render index template" do
&#160;&#160;&#160;&#160;&#160; do_get
&#160;&#160;&#160;&#160;&#160; response.should render_template('index')
&#160;&#160;&#160; end
&#160;
&#160;&#160;&#160; it "should find all products" do
&#160;&#160;&#160;&#160;&#160; Product.should_receive(:find).with(:all).and_return([@product])
&#160;&#160;&#160;&#160;&#160; do_get
&#160;&#160;&#160; end
&#160;
&#160;&#160;&#160; it "should assign the found products [...]]]></description>
			<content:encoded><![CDATA[<p>消除Spec中的冗余，减少浪费。</p>
<p>看到ben的Blog写了一篇关于Rspec的测试宏的文章：<br />
http://www.benmabey.com/2008/06/08/writing-macros-in-rspec/</p>
<p>其实很多人都是看到Tammer Saleh在MountainWest_Ruby_Conference2008上的Shoulda演示后，和我有一样的感想，就是如果如此DSL化，如此DRY的测试宏能用在Rspec上那就好了。那时我还把Shoulda的官方文档翻译了一下=_=，还有人和我讨论为什么要用Shoulda，还说他就是喜欢Rspec，其实我一次也没有用过Shoulda，但就是觉得这个DSL写的很好。不过Shoulda的缺点也很明显，AR的测试宏依赖于fixture，在业界不提倡使用fixture的情况下还有对测试数据的控制粒度的角度来说，这个做法是不受欢迎的。Rspec中提倡的是全部数据都是在测试时手动Mock出来，所以在1.1.4中才有了stub_mock!这个方法来减轻Mock对象的负担。</p>
<p>Rspec测试的粒度是比较细的，测试的覆盖面在Stroy框架出来之后也能和之前Rails提供的Unittest一样。但是Rspec的测试代码，看上去很冗余，一开始就有这种感觉，一直到看到了Shoulda才发现原来它冗余的地方是什么，这存在于很多地方，比如Controller中每次都是mock一个请求方法，然后就对各种会触发的行为和保存的状态进行断言。这些每次千篇一律的东西，我在想如果在每个context下定义一个请求方法（do_xxx之类的），然后在测试时会在测试方法内部的断言前或断言后自动调用它，这样就能减少很多冗余了。当然我在看完了Shoulda的文档后也尝试写出Rspec的测试宏，不过由于不知道怎么连接到Rspec中就放弃了，话说回来，Rspec中每个测试中上下文关系是很复杂的。</p>
<p>不说废话了，看看鬼佬们怎么减少Rspec中的冗余吧。</p>
<p>下面是一个常见的以Product为领域模型的Controller的测试，用Rspec-Rails插件生成的Scaffold的测试就类似下面这样：</p>
<p><code>describe ProductsController do<br />
&nbsp; describe "handling GET /products" do<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; before(:each) do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @product = mock_model(Products)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Product.stub!(:find).and_return([@product])<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; def do_get<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get :index<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; it "should be successful" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_get<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should be_success<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; it "should render index template" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_get<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should render_template('index')<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; it "should find all products" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Product.should_receive(:find).with(:all).and_return([@product])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_get<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; it "should assign the found products for the view" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_get<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assigns[:products].should == [@product]<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
end</code></p>
<p>上面的代码一看过去就觉得很多重复吧。如果我想让它变成下面这些DSL化的测试代码要怎么办呢？</p>
<p><code>describe ProductsController do<br />
&nbsp; describe "处理Get&nbsp;/products" do<br />
&nbsp;&nbsp;&nbsp; before(:each) do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @products = mock_model(Product)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Products.stub!(:find).and_return([@product])<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; def do_get<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get :index<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; it_should_response_success<br />
&nbsp;&nbsp;&nbsp; it_should_render :template, "index"<br />
&nbsp;&nbsp;&nbsp; it_should_receive Product, :find, :all, [@product]<br />
&nbsp;&nbsp;&nbsp; it_should_assign :products, [@product]<br />
&nbsp; end<br />
end</code></p>
<p>那么首先为这些宏定义一个Module吧：</p>
<p><code>module ControllersMacro<br />
&nbsp; module ExampleMethods<br />
&nbsp;&nbsp;&nbsp; def do_action<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; verb = [:get, :post, :put, :delete].find{|verb| respond_to? :"do_#{verb}"}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise "No do_get, do_post_ do_put, or do_delete has been defined!" unless verb<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; send("do_#{verb}")<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; module ExampleGroupMethods<br />
&nbsp;&nbsp;&nbsp; def it_should_assign(variable_name, value=nil)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should assign #{variable_name} to the view" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value ||= instance_variable_get("@#{variable_name}")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if value.kind_of?(String) &amp;&amp; value.starts_with?("@")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value = instance_variable_get(value)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_action<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assigns[variable_name].should == value<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; def it_should_response_success<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should be successful" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_action<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should be_success<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; def it_should_receive model, action, with_value = anything, return_value = anything<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should make #{model.to_s} #{action.to_s}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model.should_receive(action).with(with_value).and_return(return_value)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_action<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def self.included(receiver)<br />
&nbsp;&nbsp;&nbsp; receiver.extend&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExampleGroupMethods<br />
&nbsp;&nbsp;&nbsp; receiver.send :include, ExampleMethods<br />
&nbsp; end<br />
end</code></p>
<p>这些就是Spec中的DSL，一般称为Rspec Macros，Rspec宏。那么那么把这些宏与Controller们挂钩呢？每次测试挂一次？当然不是，在ben那篇Blog的留言里，Rspec的核心开发成员David Chelimsky给出了答案，原来Rspec中本来就有接口开放了：</p>
<p><code>Spec::Runner.configure do |config|<br />
&nbsp; #...<br />
&nbsp; config.include(ControllerMacros, :type =&gt; :controllers)<br />
end</code></p>
<p>这样就把测试宏挂到了Controller的Spec那里，那还等什么就直接在Spec用这些DSL来写出清爽的Spec吧，享受BDD。在这之后当然，我们不会止步于只在Controller中消除冗余，我立马就想到了Shoulda中几个Api，像下面那样，马上就能想到一些ActiveRecord的测试宏。</p>
<p><code>module ModelsMacro<br />
&nbsp; module ExampleMethods<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #......<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; module ExampleGroupMethods<br />
&nbsp;&nbsp;&nbsp; def it_should_require_attributes(variable_name)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should require #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; def it_should_require_unique_attributes variable_name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should require unique attributes #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; def&nbsp;&nbsp;&nbsp; it_should_not_allow_values_for variable_name, not_allow = []<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should require #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; def it_should_allow_values_for variable_name, allow_values = []<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should allow values for #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; def it_should_protect_attributes variable_name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should protect attributes #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; def it_should_have_one variable_name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should have one #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; def it_should_have_many variable_name, option =&gt; {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should have many #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; def it_should_belong_to variable_name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it "should belong to #{variable_name}" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def self.included(receiver)<br />
&nbsp;&nbsp;&nbsp; receiver.extend&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExampleGroupMethods<br />
&nbsp;&nbsp;&nbsp; receiver.send :include, ExampleMethods<br />
&nbsp; end<br />
end</code></p>
<p>如果觉得自己写很麻烦，那就用别人做好的现成的东西吧：<br />
一个现成的Rspec宏项目，Skinny Spec。它已经完成了Controller和AR的测试宏，页面的测试宏，还有一个生成器：<br />
<a href="http://github.com/rsl/skinny_spec/tree">http://github.com/rsl/skinny_spec/tree</a><br />
使用很简单，只要用script/plugin安装就好了。不过这个还有些不足，比如还没有shoulda中那个should_be_restful这个最魔幻的方法，在控制器中做出请求动作的那个方法的定义是实现一个名为shared_request方法，在其中加入请求的方法和参数。</p>
<p>其实我对Rspec还有很多想法，比如更加DSL化的测试，对Mock测试数据时更加强大的控制，测试中描述信息的国际化，动态生成测试方法等等。</p>
<p>清爽的Rspec代码，相信每个人都想把它放进自己的项目中。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/23/refactoring_rspec_code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>收回来</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/20/%e6%94%b6%e5%9b%9e%e6%9d%a5/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/20/%e6%94%b6%e5%9b%9e%e6%9d%a5/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 07:28:52 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[总结]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/20/%e6%94%b6%e5%9b%9e%e6%9d%a5/</guid>
		<description><![CDATA[大学三年里好像不知不觉就学到了很多东西，感觉自己学的很泛很散。我这个人好奇心很强，所以东学一下，西学一下，很多东西都是学到了皮毛。
现在要把自己的知识面收回来，收到一个比较小的知识面上，然后好好把这部分知识学习得深入些。还有就是不要研究过多的过程的东西，比如敏捷，只要了解一下就好了。
编程语言：Ruby，Cpp，C，Erlang，就这四门就够了。整个计算机世界的底层就是C构建出来的，如果要再上一层就是Cpp，要面向对象要DSL就是继承Smalltalk之魂的Ruby，并发的FP语言Erlang很有前途的。D语言的话，以后有机会要用到再说，而Java要用的时候查查书就可以。说什么语言都是一样的人，我觉得是放屁。
开发技术也有几个方向：Web开发，编译器解析器等语言底层构建技术，自动化测试和TDD/BDD。应该就这些了，对于敏捷还是看看就算了，到了实际软件开发的问题开始的时候再考虑这些方法，其实敏捷的经典书籍我也基本看了。
多看看源码。其实现在我看源码的感觉是这样，大概看得懂，可是不懂得怎么改。唉呀呀，还需要修炼。
实践也还是很少。自己有时会写写一些算法的实现，有时会写些小demo。其实我的想法蛮多的，想作的东西也是很多的，但是并不是十分有动力去把这些想法做出来。这次有机会参与到老师的科研项目就要努力去完成它，还有要下定决心完成一个编译器也是一个不错的开始。上次比赛作的那个日程管理平台也是一个不错的东西，其实可以把以前想做的，那个依照《高效人士七个习惯》里提出的日程管理的方法，以Web化的方式实现在这个平台上，要继续开发下去。
自己的不足，对于很多技术的简单应用其实还是游刃有余的状态，但是代码/系统开始复杂的时候就开始手足无措了；看书也很努力很认真，可是思考和总结还是很少，作笔记太少；平时开发时遇到问题时没有作记录下解决方法，之后遇到相同的问题又去查找了一次，太低效率的做法了；有买书强迫症，看到好书就想买，不会太管自己身上还有多少钱，买来又看不完，买了的一些书到现在还只是看完了前言，又浪费钱又阻住地方；英语现在还是太烂，能翻译文档又怎样，能用简单的词语和鬼佬交流又怎样，很多文章还是要一边查词一边看，口语又烂，英文技术写作能力又不行，英语真的是一个相当相当重要的一个工具；数学不行，越来越发现数学的重要，计算机世界本来就是构建在大量的数学定理和分析方法之上的。其实领导能力也是很重要的，自己一个人能做出一个东西，再怎样也是有限的，只有能领导一批人完成一个东西才是真的厉害。
看到了不足就要改进。还有有一个不错的工具，panda和toplang上的同学也经常提到的，那就是Google Notes，好好利用这个工具。
我相信，未来只能由自己创造，自己就是自己的救世主。现在还是和我的理想差的远了，还要努力才行，我要变得很厉害很厉害。
]]></description>
			<content:encoded><![CDATA[<p>大学三年里好像不知不觉就学到了很多东西，感觉自己学的很泛很散。我这个人好奇心很强，所以东学一下，西学一下，很多东西都是学到了皮毛。</p>
<p>现在要把自己的知识面收回来，收到一个比较小的知识面上，然后好好把这部分知识学习得深入些。还有就是不要研究过多的过程的东西，比如敏捷，只要了解一下就好了。</p>
<p>编程语言：Ruby，Cpp，C，Erlang，就这四门就够了。整个计算机世界的底层就是C构建出来的，如果要再上一层就是Cpp，要面向对象要DSL就是继承Smalltalk之魂的Ruby，并发的FP语言Erlang很有前途的。D语言的话，以后有机会要用到再说，而Java要用的时候查查书就可以。说什么语言都是一样的人，我觉得是放屁。</p>
<p>开发技术也有几个方向：Web开发，编译器解析器等语言底层构建技术，自动化测试和TDD/BDD。应该就这些了，对于敏捷还是看看就算了，到了实际软件开发的问题开始的时候再考虑这些方法，其实敏捷的经典书籍我也基本看了。</p>
<p>多看看源码。其实现在我看源码的感觉是这样，大概看得懂，可是不懂得怎么改。唉呀呀，还需要修炼。</p>
<p>实践也还是很少。自己有时会写写一些算法的实现，有时会写些小demo。其实我的想法蛮多的，想作的东西也是很多的，但是并不是十分有动力去把这些想法做出来。这次有机会参与到老师的科研项目就要努力去完成它，还有要下定决心完成一个编译器也是一个不错的开始。上次比赛作的那个日程管理平台也是一个不错的东西，其实可以把以前想做的，那个依照《高效人士七个习惯》里提出的日程管理的方法，以Web化的方式实现在这个平台上，要继续开发下去。</p>
<p>自己的不足，对于很多技术的简单应用其实还是游刃有余的状态，但是代码/系统开始复杂的时候就开始手足无措了；看书也很努力很认真，可是思考和总结还是很少，作笔记太少；平时开发时遇到问题时没有作记录下解决方法，之后遇到相同的问题又去查找了一次，太低效率的做法了；有买书强迫症，看到好书就想买，不会太管自己身上还有多少钱，买来又看不完，买了的一些书到现在还只是看完了前言，又浪费钱又阻住地方；英语现在还是太烂，能翻译文档又怎样，能用简单的词语和鬼佬交流又怎样，很多文章还是要一边查词一边看，口语又烂，英文技术写作能力又不行，英语真的是一个相当相当重要的一个工具；数学不行，越来越发现数学的重要，计算机世界本来就是构建在大量的数学定理和分析方法之上的。其实领导能力也是很重要的，自己一个人能做出一个东西，再怎样也是有限的，只有能领导一批人完成一个东西才是真的厉害。</p>
<p>看到了不足就要改进。还有有一个不错的工具，panda和toplang上的同学也经常提到的，那就是Google Notes，好好利用这个工具。</p>
<p>我相信，未来只能由自己创造，自己就是自己的救世主。现在还是和我的理想差的远了，还要努力才行，我要变得很厉害很厉害。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/20/%e6%94%b6%e5%9b%9e%e6%9d%a5/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>差距</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/20/%e5%b7%ae%e8%b7%9d/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/20/%e5%b7%ae%e8%b7%9d/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 16:48:21 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/20/%e5%b7%ae%e8%b7%9d/</guid>
		<description><![CDATA[我和一些同样在技术之路上的同龄人具有不小的差距，如Male，还有以前金中去了MS的那个人等。
其实这些差距很多人都说是来自小时候的教育，那些人家庭教育背景都是不错的，父母都是大学毕业，或者知识水平比较高。他们都很早就接触了计算机（是接触了计算机而不是接触游戏），小时候就学会了英语。比如云风，初中就开始学习编程，比如toplang里的一些人说到的，高中初中就读了编译原理这一类的计算机经典理论书籍。
不过大部分人应该都是到了大学才真正的开始接触，学习计算机知识。其实如果来到大学之前，对计算机有所了解但不是掌握很多的话，其实四年（其实还不够四年就是大一到大四前段）也就是全部的学习时间。大一还是在懵懵懂懂，在摸索自己的技术之路，到了大二开始知道怎么学习基础，到了大三，开始要想去作些东西，到了大四，没时间了。
其实四年很短，这就拉开了和一开始就接受了很好教育的人的差距。到了工作的时候，如果自己不挤榨时间来学习的话就没有学习的机会了，最近在忙的时候这种感觉特别的重。
]]></description>
			<content:encoded><![CDATA[<p>我和一些同样在技术之路上的同龄人具有不小的差距，如<a href="http://pluskid.lifegoo.com">Male</a>，还有以前金中去了MS的那个人等。</p>
<p>其实这些差距很多人都说是来自小时候的教育，那些人家庭教育背景都是不错的，父母都是大学毕业，或者知识水平比较高。他们都很早就接触了计算机（是接触了计算机而不是接触游戏），小时候就学会了英语。比如云风，初中就开始学习编程，比如toplang里的一些人说到的，高中初中就读了编译原理这一类的计算机经典理论书籍。</p>
<p>不过大部分人应该都是到了大学才真正的开始接触，学习计算机知识。其实如果来到大学之前，对计算机有所了解但不是掌握很多的话，其实四年（其实还不够四年就是大一到大四前段）也就是全部的学习时间。大一还是在懵懵懂懂，在摸索自己的技术之路，到了大二开始知道怎么学习基础，到了大三，开始要想去作些东西，到了大四，没时间了。</p>
<p>其实四年很短，这就拉开了和一开始就接受了很好教育的人的差距。到了工作的时候，如果自己不挤榨时间来学习的话就没有学习的机会了，最近在忙的时候这种感觉特别的重。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/20/%e5%b7%ae%e8%b7%9d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guile</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/19/guile/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/19/guile/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 14:54:32 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[SICP]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/19/guile/</guid>
		<description><![CDATA[Guile，一个GNU的Scheme的解析器。
官站：http://www.gnu.org/software/guile
很好玩的一个解析器，在学习《SICP》的好工具，而且带有如何实现的文档，翻了一下它的文档，好像与MRI Ruby差不多，支持C 扩展。这是个不错的解析器的参考。
最近比较忙，学习时间只有中午和睡觉前这段时间，可以我还是要努力，我要成为能够被人记住的一个开发者。
]]></description>
			<content:encoded><![CDATA[<p>Guile，一个GNU的Scheme的解析器。</p>
<p>官站：<a href="http://www.gnu.org/software/guile">http://www.gnu.org/software/guile</a></p>
<p>很好玩的一个解析器，在学习《SICP》的好工具，而且带有如何实现的文档，翻了一下它的文档，好像与MRI Ruby差不多，支持C 扩展。这是个不错的解析器的参考。</p>
<p>最近比较忙，学习时间只有中午和睡觉前这段时间，可以我还是要努力，我要成为能够被人记住的一个开发者。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/19/guile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一段生成日历的代码</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/17/%e4%b8%80%e6%ae%b5%e7%94%9f%e6%88%90%e6%97%a5%e5%8e%86%e7%9a%84%e4%bb%a3%e7%a0%81/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/17/%e4%b8%80%e6%ae%b5%e7%94%9f%e6%88%90%e6%97%a5%e5%8e%86%e7%9a%84%e4%bb%a3%e7%a0%81/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 17:19:06 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/17/%e4%b8%80%e6%ae%b5%e7%94%9f%e6%88%90%e6%97%a5%e5%8e%86%e7%9a%84%e4%bb%a3%e7%a0%81/</guid>
		<description><![CDATA[
&#160; def month_day(month, year=Date.today.year)
&#160;&#160;&#160; mdays = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
&#160;&#160;&#160; mdays[2] = 29 if Date.leap?(year)
&#160;&#160;&#160; mdays[month]
&#160; end
&#160;
&#160; def calendar(month, year)
&#160;&#160;&#160; days = month_day(month, year)
&#160;&#160;&#160; t = Time.mktime(year, month, 1)
&#160;&#160;&#160; first = t.wday
&#160;&#160;&#160; list = *1..days
&#160;&#160;&#160; weeks = [[]]
&#160;&#160;&#160; week1 = 7 - first
&#160;&#160;&#160; week1.times { weeks[0] [...]]]></description>
			<content:encoded><![CDATA[<p><code><br />
&nbsp; def month_day(month, year=Date.today.year)<br />
&nbsp;&nbsp;&nbsp; mdays = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]<br />
&nbsp;&nbsp;&nbsp; mdays[2] = 29 if Date.leap?(year)<br />
&nbsp;&nbsp;&nbsp; mdays[month]<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def calendar(month, year)<br />
&nbsp;&nbsp;&nbsp; days = month_day(month, year)<br />
&nbsp;&nbsp;&nbsp; t = Time.mktime(year, month, 1)<br />
&nbsp;&nbsp;&nbsp; first = t.wday<br />
&nbsp;&nbsp;&nbsp; list = *1..days<br />
&nbsp;&nbsp;&nbsp; weeks = [[]]<br />
&nbsp;&nbsp;&nbsp; week1 = 7 - first<br />
&nbsp;&nbsp;&nbsp; week1.times { weeks[0] &amp;lt;&amp;lt; list.shift }<br />
&nbsp;&nbsp;&nbsp; nweeks = list.size/7 + 1<br />
&nbsp;&nbsp;&nbsp; nweeks.times do |i|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weeks[i+1] ||= []<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.times do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break if list.empty?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weeks[i+1] &amp;lt;&amp;lt; list.shift<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; pad_first = 7 - weeks[0].size<br />
&nbsp;&nbsp;&nbsp; pad_first.times { weeks[0].unshift(nil) }<br />
&nbsp;&nbsp;&nbsp; pad_last = 7 - weeks[0].size<br />
&nbsp;&nbsp;&nbsp; pad_last.times { weeks[-1].unshift(nil) }<br />
&nbsp;&nbsp;&nbsp; weeks<br />
&nbsp; end<br />
&nbsp;<br />
&nbsp; def calendar_table(month, year)<br />
&nbsp;&nbsp;&nbsp; today = Time.now.day<br />
&nbsp;&nbsp;&nbsp; table_body = ""<br />
&nbsp;&nbsp;&nbsp; calendar(month, year).each do |week|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table_body += "&amp;lt;tr&amp;gt;"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; week.each do |day|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if day.nil?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table_body += "&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table_body += (day == today) ? "&amp;lt;td class='today'&amp;gt;" : "&amp;lt;td&amp;gt;"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table_body += "#{day}&amp;lt;/td&amp;gt;"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table_body += "&amp;lt;/tr&amp;gt;"<br />
&nbsp;&nbsp;&nbsp; end<br />
&nbsp;&nbsp;&nbsp; table_body<br />
&nbsp; end<br />
</code></p>
<p>calendar(month, year)方法其实是《The Ruby Way》里面的。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/17/%e4%b8%80%e6%ae%b5%e7%94%9f%e6%88%90%e6%97%a5%e5%8e%86%e7%9a%84%e4%bb%a3%e7%a0%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>准备写个编译器</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/06/06/%e5%87%86%e5%a4%87%e5%86%99%e4%b8%aa%e7%bc%96%e8%af%91%e5%99%a8/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/06/06/%e5%87%86%e5%a4%87%e5%86%99%e4%b8%aa%e7%bc%96%e8%af%91%e5%99%a8/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 17:35:32 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/06/06/%e5%87%86%e5%a4%87%e5%86%99%e4%b8%aa%e7%bc%96%e8%af%91%e5%99%a8/</guid>
		<description><![CDATA[现在就要准备毕业设计了，打算暑假留在学校这里。编译器不是个简单的东西，就算做出来了，如主任说的“千里马需要伯乐，如果你做了这个出来，老师们没有兴趣看这个，那也没用。”
其实现在是想作编译器，但是最后可能会做出一个C语言的解析器（让C动起来）的东西，很难说。最近在关注一个Ruby VM，Rubinius，想让Ruby实现Ruby VM的项目。这个东西满有参考价值的，而且可以的话我也想参与到其中。而Rubinius的开发方式是挺特别的，大家都可以提交mspec（用BDD的形式描述VM的运行），然后项目开发者们就实现相关的代码，过几天我把我从Rubinius那里了解到的东西写一下。或许还会翻译一些Rubinius的文档。
要作编译器或者VM，那需要编译原理等知识，下面列举一下所需知识和资料：
程序设计语言原理，其中包括语法，语义的解析等等。《SICP》，《程序设计语言实践之路》。
编译原理，其中包括代码解析，运行时环境构建等等。《编译原理2e》，《现代编译原理-C语言描述》（龙虎两书）
我其实是想在这个过程中学习到更多东西，如果真的可以写出来的话，自己的思想应该就不会像现在那么幼稚了。做个编译器／解析器的第一步应该就是能做出一个Scheme的解析器。
]]></description>
			<content:encoded><![CDATA[<p>现在就要准备毕业设计了，打算暑假留在学校这里。编译器不是个简单的东西，就算做出来了，如主任说的“千里马需要伯乐，如果你做了这个出来，老师们没有兴趣看这个，那也没用。”</p>
<p>其实现在是想作编译器，但是最后可能会做出一个C语言的解析器（让C动起来）的东西，很难说。最近在关注一个Ruby VM，Rubinius，想让Ruby实现Ruby VM的项目。这个东西满有参考价值的，而且可以的话我也想参与到其中。而Rubinius的开发方式是挺特别的，大家都可以提交mspec（用BDD的形式描述VM的运行），然后项目开发者们就实现相关的代码，过几天我把我从Rubinius那里了解到的东西写一下。或许还会翻译一些Rubinius的文档。</p>
<p>要作编译器或者VM，那需要编译原理等知识，下面列举一下所需知识和资料：</p>
<p>程序设计语言原理，其中包括语法，语义的解析等等。《SICP》，《程序设计语言实践之路》。<br />
编译原理，其中包括代码解析，运行时环境构建等等。《编译原理2e》，《现代编译原理-C语言描述》（龙虎两书）</p>
<p>我其实是想在这个过程中学习到更多东西，如果真的可以写出来的话，自己的思想应该就不会像现在那么幼稚了。做个编译器／解析器的第一步应该就是能做出一个Scheme的解析器。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/06/06/%e5%87%86%e5%a4%87%e5%86%99%e4%b8%aa%e7%bc%96%e8%af%91%e5%99%a8/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rspec 1.1.4版的新特性</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/29/rspec-114%e7%89%88%e7%9a%84%e6%96%b0%e7%89%b9%e6%80%a7/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/29/rspec-114%e7%89%88%e7%9a%84%e6%96%b0%e7%89%b9%e6%80%a7/#comments</comments>
		<pubDate>Thu, 29 May 2008 09:45:16 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/29/rspec-114%e7%89%88%e7%9a%84%e6%96%b0%e7%89%b9%e6%80%a7/</guid>
		<description><![CDATA[Rspec新版本发布了。来看看它又带来了什么。
hash_including方法，它能让开发者在Mock接受参数时不用指定全部参数，只需要指定应包含某个键值对。示例代码如下：# beforeaccount.should_receive(:deposit).with({:amount =&#62; 37.42, :date =&#62; anything()})# in 1.1.4account.should_receive(:deposit).with(hash_including(:amount =&#62; 37.42))修正了heckle支持的bug。
stub_model方法出现了，再也不用在View Spec里用mock_model之后，一个一个属性写上去了。这个方法
参考：http://blog.davidchelimsky.net/articles/2008/05/27/rspec-1-1-4
]]></description>
			<content:encoded><![CDATA[<p>Rspec新版本发布了。来看看它又带来了什么。</p>
<p>hash_including方法，它能让开发者在Mock接受参数时不用指定全部参数，只需要指定应包含某个键值对。示例代码如下：<br /><code><br /># before<br />account.should_receive(:deposit).with({:amount =&gt; 37.42, :date =&gt; anything()})<br /># in 1.1.4<br />account.should_receive(:deposit).with(hash_including(:amount =&gt; 37.42))<br /></code><br />修正了heckle支持的bug。</p>
<p>stub_model方法出现了，再也不用在View Spec里用mock_model之后，一个一个属性写上去了。这个方法</p>
<p>参考：<br /><a href="http://blog.davidchelimsky.net/articles/2008/05/27/rspec-1-1-4">http://blog.davidchelimsky.net/articles/2008/05/27/rspec-1-1-4</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/29/rspec-114%e7%89%88%e7%9a%84%e6%96%b0%e7%89%b9%e6%80%a7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>谷歌开放Google App Engine</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/29/%e8%b0%b7%e6%ad%8c%e5%bc%80%e6%94%begoogle-app-engine/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/29/%e8%b0%b7%e6%ad%8c%e5%bc%80%e6%94%begoogle-app-engine/#comments</comments>
		<pubDate>Thu, 29 May 2008 03:12:36 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/29/%e8%b0%b7%e6%ad%8c%e5%bc%80%e6%94%begoogle-app-engine/</guid>
		<description><![CDATA[http://code.google.com/appengine/
谷歌开放了免费的App Engine，500M的储存空间＆5百万的每月PV。看了一下之后是基于Py的，最简单的HelloWorld只要写个输出的Py脚本再用个yaml指定请求的路由处理。如果是需要更加复杂的处理就是要使用谷歌提供的Web框架，其中包装了Django等框架。看来是个不错的机会学习Py和Py的WebApp开发。感觉好像是谷歌开始要推广Py。
在YouTube的视频介绍：
http://www.youtube.com/watch?v=3Ztr-HhWX1c
http://www.youtube.com/watch?v=tcbpTQXNwac
http://www.youtube.com/watch?v=oG6Ac7d-Nx8
http://www.youtube.com/watch?v=oTFL7FPLnXY
http://www.youtube.com/watch?v=JcM2Ejk1tis
http://www.youtube.com/watch?v=K7usoKm5zwE
不知道是不是RP问题，创建时一直提示域名不可用&#8230;&#8230;或许毕业后会去作个Pyer或者Cpper，而不是Rubyist。
]]></description>
			<content:encoded><![CDATA[<p>http://code.google.com/appengine/</p>
<p>谷歌开放了免费的App Engine，500M的储存空间＆5百万的每月PV。看了一下之后是基于Py的，最简单的HelloWorld只要写个输出的Py脚本再用个yaml指定请求的路由处理。如果是需要更加复杂的处理就是要使用谷歌提供的Web框架，其中包装了Django等框架。看来是个不错的机会学习Py和Py的WebApp开发。感觉好像是谷歌开始要推广Py。</p>
<p>在YouTube的视频介绍：<br />
http://www.youtube.com/watch?v=3Ztr-HhWX1c<br />
http://www.youtube.com/watch?v=tcbpTQXNwac<br />
http://www.youtube.com/watch?v=oG6Ac7d-Nx8<br />
http://www.youtube.com/watch?v=oTFL7FPLnXY<br />
http://www.youtube.com/watch?v=JcM2Ejk1tis<br />
http://www.youtube.com/watch?v=K7usoKm5zwE</p>
<p>不知道是不是RP问题，创建时一直提示域名不可用&#8230;&#8230;或许毕业后会去作个Pyer或者Cpper，而不是Rubyist。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/29/%e8%b0%b7%e6%ad%8c%e5%bc%80%e6%94%begoogle-app-engine/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>试用c.vim</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/28/%e8%af%95%e7%94%a8cvim/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/28/%e8%af%95%e7%94%a8cvim/#comments</comments>
		<pubDate>Wed, 28 May 2008 15:36:13 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/28/%e8%af%95%e7%94%a8cvim/</guid>
		<description><![CDATA[c.vim（C-support）是一个vim插件，C/Cpp开发的助推器，这个系列还有一个lua和Bash的版本。
不废话了，先看看它的主要功能先。
首先是代码模板：
  &#8212; Statements &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;
  \sd       do { } while                        (n,v,i)
  \sf       for      [...]]]></description>
			<content:encoded><![CDATA[<p>c.vim（C-support）是一个vim插件，C/Cpp开发的助推器，这个系列还有一个lua和Bash的版本。</p>
<p>不废话了，先看看它的主要功能先。</p>
<p>首先是代码模板：</p>
<p>  &#8212; Statements &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>  \sd       do { } while                        (n,v,i)<br />
  \sf       for                                 (n,i)<br />
  \sfo      for { }                             (n,v,i)<br />
  \si       if                                  (n,i)<br />
  \sif      if { }                              (n,v,i)<br />
  \sie      if else                             (n,v,i)<br />
  \sife     if { } else { }                     (n,v,i)<br />
  \sw       while                               (n,i)<br />
  \swh      while { }                           (n,v,i)<br />
  \ss       switch                              (n,v,i)<br />
  \sc       case                                (n,i)<br />
  \s{       { }                                 (n,v,i)</p>
<p>  &#8212; Preprocessor &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>  \p&lt;       #include &lt;&amp;gt;                         (n,i)<br />
  \p&#8221;       #include &#8220;&#8221;                         (n,i)<br />
  \pd       #define                             (n,i)<br />
  \pu       #undef                              (n,i)<br />
  \pie      #if  #else #endif                   (n,v,i)<br />
  \pid      #ifdef #else #endif                 (n,v,i)<br />
  \pin      #ifndef #else #endif                (n,v,i)<br />
  \pind     #ifndef #def #endif                 (n,v,i)<br />
  \pi0      #if 0 #endif                        (n,v,i)<br />
  \pr0      remove #if 0 #endif                 (n)<br />
  &#8212; Idioms &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>  \if       function                            (n,v,i)<br />
  \isf      static function                     (n,v,i)<br />
  \im       main()                              (n,v,i)<br />
  \i0       for( x=0; x&lt;n; x+=1 )               (n,v,i)<br />
  \in       for( x=n-1; x&gt;=0; x-=1 )            (n,v,i)<br />
  \ie       enum   + typedef                    (n,i)<br />
  \is       struct + typedef                    (n,i)<br />
  \iu       union  + typedef                    (n,i)<br />
  \ip       printf()                            (n,i)<br />
  \isc      scanf()                             (n,i)<br />
  \ica      p=calloc()                          (n,i)<br />
  \ima      p=malloc()                          (n,i)<br />
  \isi      sizeof()                            (n,v,i)<br />
  \ias      assert()                            (n,v)<br />
  \ii       open input file                     (n,i)<br />
  \io       open output file                    (n,i)</p>
<p>  &#8212; Snippets &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>  \nr       read code snippet                   (n)<br />
  \nw       write code snippet                  (n,v)<br />
  \ne       edit code snippet                   (n)<br />
  \np       pick up prototype                   (n,v)<br />
  \ni       insert prototype(s)                 (n)<br />
  \nc       clear  prototype(s)                 (n)<br />
  \ns       show   prototype(s)                 (n)</p>
<p>  &#8212; C++ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>  \+c       class                               (n,i)<br />
  \+cn      class (using new)                   (n,i)<br />
  \+ci      class implementation                (n,i)<br />
  \+cni     class (using new) implementation    (n,i)<br />
  \+mi      method implementation               (n,i)<br />
  \+ai      accessor implementation             (n,i)</p>
<p>  \+tc      template class                      (n,i)<br />
  \+tcn     template class (using new)          (n,i)<br />
  \+tci     template class implementation       (n,i)<br />
  \+tcni    template class (using new) impl.    (n,i)<br />
  \+tmi     template method implementation      (n,i)<br />
  \+tai     template accessor implementation    (n,i)</p>
<p>  \+tf      template function                   (n,i)<br />
  \+ec      error class                         (n,i)<br />
  \+tr      try &#8230; catch                       (n,v,i)<br />
  \+ca      catch                               (n,v,i)<br />
  \+c.      catch(&#8230;)                          (n,v,i)</p>
<p>这个表最左边的就是按键，中间就是对应的模板，最后面是对应的模式。n是normal，i就是插入模式，v是虚拟模式。展开的模板放在 ~/.vim/c-support/templates 这里，自己可以hack，比如第一件事就是把Templates中的个人资料改一下。我还把函数声明改了一下，默认是把返回值类型放到上一行，看起来不爽。</p>
<p>然后就是编译链接和运行代码啦，我只用快捷键。</p>
<p>       F9   compile and link<br />
   Alt-F9   write buffer and compile<br />
  Ctrl-F9   run executable<br />
 Shift-F9   set command line arguments</p>
<p> Shift-F2   switch between source files and header files</p>
<p>有了这些快捷键之后加上Vim7本身就有的一点点补全功能，其实这个工具也有些IDEful了。</p>
<p>最后看看一些实用功能，比如代码和注释的转化，还有行尾插入注释，插入注释行等等。</p>
<p>  &#8212; Comments &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>  \cl       end-of-line comment                 (n,v,i)<br />
  \cj       adjust end-of-line comment(s)       (n,v,i)<br />
  \cs       set end-of-line comment column      (n)<br />
  \c*       code -&gt; comment /* */               (n,v)<br />
  \c/       code -&gt; comment //                  (n,v)<br />
  \cc       code -&gt; comment //                  (n,v)<br />
  \co       comment -&gt; code                     (n,v)<br />
  \cfr      frame comment                       (n,i)<br />
  \cfu      function comment                    (n,i)<br />
  \cme      method description                  (n,i)<br />
  \ccl      class description                   (n,i)<br />
  \cd       date                                (n,i)<br />
  \ct       date \&amp; time                        (n,i)</p>
<p>有空试用一下lua-support和bash-support。其实一直想写篇rails.vim的配置和使用和一点点Src分析。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/28/%e8%af%95%e7%94%a8cvim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TCppPL中的一段话</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/28/tcpppl%e4%b8%ad%e7%9a%84%e4%b8%80%e6%ae%b5%e8%af%9d/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/28/tcpppl%e4%b8%ad%e7%9a%84%e4%b8%80%e6%ae%b5%e8%af%9d/#comments</comments>
		<pubDate>Wed, 28 May 2008 14:59:15 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Reading]]></category>
		<category><![CDATA[Thinking]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/28/tcpppl%e4%b8%ad%e7%9a%84%e4%b8%80%e6%ae%b5%e8%af%9d/</guid>
		<description><![CDATA[这是在B.Stroustrup的TCppPL中Chapter2最后结尾的一段话：
没有一种程序设计语言是完美无缺的。幸运的是，一种程序设计语言不必是完美无缺的，也可以成为构造伟大系统的良好工具。事实上，一种通用的程序设计语言根本不可能对它被用于的所有工作都是最完美的，对一项工作来说最完美的东西对于另外的工作就常常会表现出严重的缺陷，因为在一个领域中的最完美事物实际上也就是意味着专门化。Cpp的设计是想成为构造范围广泛多样的系统的良好工具，而且能够直接表达范围广泛多样的思想。
并不是所有的东西都能直接通过语言的某些内部特征表述。事实上，这也不应该成为一种理想。语言特征的存在是为了支持各种各样的程序设计风格和技术，因此，学习一种语言的工作就应该集中于去把握对该语言而言固有的和自然的风格－－而不是去理解该语言所有语言特征的细枝末节。
在实践性的程序设计中，理解语言中最晦涩难懂的语言特征，或者使用最大量的不同特征并不能获得什么利益。把一种特征孤立起来看并没有什么意思，只是在由技术和其他特征所形成的环境里，这一特征才获得了意义和趣味。因此，在阅读后面的章节时请牢记，考察Cpp的各种细节的真实目的在于能够应用它们，在有效的环境里，去支持良好的程序设计风格。

Bjarne真的是一个超人级的人物，很早就看清了程序设计语言的真谛。这段话的意思人人都懂吧。（还有赞叹一下裘掌门的翻译功力）
上次Topcoder的比赛很失败，让我觉着自己。这让我又回过头来再看Cpp的书，看Cpp圣经－－TCppPL，看侯Sir的STL剖析。看着Cpp的代码有种亲切的感觉，书中Bjarne写出来的Sample，很优美干练，可读性也非常高。
其实程序设计语言规格到底还是给人来描述现实问题的，描述后让计算机来处理问题，所以能更好地解决问题的语言就是一门不错的语言。RoR最能体现专门化解决问题的思想，Ruby的DSL能力不是盖的。而创造Ruby的这些DSL或者框架的超人们，他们都是掌握了良好程序设计风格的家伙。（说到最后知不到自己在说什么）
]]></description>
			<content:encoded><![CDATA[<p>这是在B.Stroustrup的TCppPL中Chapter2最后结尾的一段话：</p>
<blockquote><p>没有一种程序设计语言是完美无缺的。幸运的是，一种程序设计语言不必是完美无缺的，也可以成为构造伟大系统的良好工具。事实上，一种通用的程序设计语言根本不可能对它被用于的所有工作都是最完美的，对一项工作来说最完美的东西对于另外的工作就常常会表现出严重的缺陷，因为在一个领域中的最完美事物实际上也就是意味着专门化。Cpp的设计是想成为构造范围广泛多样的系统的良好工具，而且能够直接表达范围广泛多样的思想。</p>
<p>并不是所有的东西都能直接通过语言的某些内部特征表述。事实上，这也不应该成为一种理想。语言特征的存在是为了支持各种各样的程序设计风格和技术，因此，学习一种语言的工作就应该集中于去把握对该语言而言固有的和自然的风格－－而不是去理解该语言所有语言特征的细枝末节。</p>
<p>在实践性的程序设计中，理解语言中最晦涩难懂的语言特征，或者使用最大量的不同特征并不能获得什么利益。把一种特征孤立起来看并没有什么意思，只是在由技术和其他特征所形成的环境里，这一特征才获得了意义和趣味。因此，在阅读后面的章节时请牢记，考察Cpp的各种细节的真实目的在于能够应用它们，在有效的环境里，去支持良好的程序设计风格。</p>
</blockquote>
<p>Bjarne真的是一个超人级的人物，很早就看清了程序设计语言的真谛。这段话的意思人人都懂吧。（还有赞叹一下裘掌门的翻译功力）</p>
<p>上次Topcoder的比赛很失败，让我觉着自己。这让我又回过头来再看Cpp的书，看Cpp圣经－－TCppPL，看侯Sir的STL剖析。看着Cpp的代码有种亲切的感觉，书中Bjarne写出来的Sample，很优美干练，可读性也非常高。</p>
<p>其实程序设计语言规格到底还是给人来描述现实问题的，描述后让计算机来处理问题，所以能更好地解决问题的语言就是一门不错的语言。RoR最能体现专门化解决问题的思想，Ruby的DSL能力不是盖的。而创造Ruby的这些DSL或者框架的超人们，他们都是掌握了良好程序设计风格的家伙。（说到最后知不到自己在说什么）</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/28/tcpppl%e4%b8%ad%e7%9a%84%e4%b8%80%e6%ae%b5%e8%af%9d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>无痛体验Rails2.1RC1</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/18/%e6%97%a0%e7%97%9b%e4%bd%93%e9%aa%8crails21rc1/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/18/%e6%97%a0%e7%97%9b%e4%bd%93%e9%aa%8crails21rc1/#comments</comments>
		<pubDate>Sun, 18 May 2008 09:52:36 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/18/%e6%97%a0%e7%97%9b%e4%bd%93%e9%aa%8crails21rc1/</guid>
		<description><![CDATA[无须升级整个系统的Rails，只需要在项目中的Rakefile中加入下面的代码，然后运行rake rails:freeze:edge：
namespace :rails do
&#160;&#160;namespace :freeze do
&#160;&#160;&#160;&#160;desc 'Lock to latest Edge Rails, for a specific release use RELEASE=1.2.0'
&#160;&#160;&#160;&#160;task :edge do
&#160;&#160;&#160;&#160;&#160;&#160;require 'open-uri'
&#160;&#160;&#160;&#160;&#160;&#160;version = ENV["RELEASE"] &#124;&#124; "edge"
&#160;&#160;&#160;&#160;&#160;&#160;target = "rails_#{version}.zip"
&#160;&#160;&#160;&#160;&#160;&#160;url = "http://dev.rubyonrails.org/archives/#{target}"
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;chdir 'vendor' do
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;puts "Downloading Rails from #{url}"
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;File.open('rails.zip', 'wb') do &#124;dst&#124;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;open url do &#124;src&#124;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;while chunk = src.read(4096)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;dst &#60;&#60; chunk
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end
&#160;&#160;&#160;&#160;&#160;&#160;end
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;puts 'Unpacking Rails'
&#160;&#160;&#160;&#160;&#160;&#160;rm_rf 'rails'
&#160;&#160;&#160;&#160;&#160;&#160;`unzip rails.zip`
&#160;&#160;&#160;&#160;&#160;&#160;%w(rails.zip rails/Rakefile rails/cleanlogs.sh rails/pushgems.rb rails/release.rb).each do &#124;goner&#124;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;rm_f [...]]]></description>
			<content:encoded><![CDATA[<p>无须升级整个系统的Rails，只需要在项目中的Rakefile中加入下面的代码，然后运行rake rails:freeze:edge：</p>
<p><code>namespace :rails do<br />
&nbsp;&nbsp;namespace :freeze do<br />
&nbsp;&nbsp;&nbsp;&nbsp;desc 'Lock to latest Edge Rails, for a specific release use RELEASE=1.2.0'<br />
&nbsp;&nbsp;&nbsp;&nbsp;task :edge do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'open-uri'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;version = ENV["RELEASE"] || "edge"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;target = "rails_#{version}.zip"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url = "http://dev.rubyonrails.org/archives/#{target}"<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chdir 'vendor' do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "Downloading Rails from #{url}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.open('rails.zip', 'wb') do |dst|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;open url do |src|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while chunk = src.read(4096)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dst &lt;&lt; chunk<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'Unpacking Rails'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rm_rf 'rails'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`unzip rails.zip`<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%w(rails.zip rails/Rakefile rails/cleanlogs.sh rails/pushgems.rb rails/release.rb).each do |goner|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rm_f goner<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;puts 'Updating current scripts, javascripts, and configuration settings'<br />
&nbsp;&nbsp;&nbsp;&nbsp;Rake::Task['rails:update'].invoke<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
end</code></p>
<p>这段代码其实是Rails2.1里的rails:freeze:edeg的Rake任务代码，因为Rails的代码库已经迁移至github，好像svn不提供新的版本，现在获取Rails最新版本的方法一是到github那里clone下来，要么就到http://dev.rubyonrails.org/archives/下载一个打包好的zip文件。</p>
<p>其实最傻瓜的方法就是直接下载http://dev.rubyonrails.org/archives/rails_edge.zip然后解压到vendor/那里，其实上面贴的rake脚本也是做了这个事情:-)</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/18/%e6%97%a0%e7%97%9b%e4%bd%93%e9%aa%8crails21rc1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>看Rails2.1RC1的Changelog</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/18/%e7%9c%8brails21%e7%9a%84changelog/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/18/%e7%9c%8brails21%e7%9a%84changelog/#comments</comments>
		<pubDate>Sun, 18 May 2008 04:13:03 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/18/%e7%9c%8brails21%e7%9a%84changelog/</guid>
		<description><![CDATA[Rails2.1RC1的Changelog也是满有趣的。

*2.1.0 RC1 (May 11th, 2008)*
* script/dbconsole fires up the command-line database client. #102 [Steve Purcell]
* Fix bug where plugin init.rb files from frozen gem specs weren&#8217;t being run. (pjb3) [#122 state:resolved]
* Made the location of the routes file configurable with config.routes_configuration_file (Scott Fleckenstein) [#88]
* Rails Edge info returns the latest git commit hash [Francesc Esplugas]
* [...]]]></description>
			<content:encoded><![CDATA[<p>Rails2.1RC1的Changelog也是满有趣的。<br />
<span id="more-93"></span></p>
<blockquote><p>*2.1.0 RC1 (May 11th, 2008)*</p>
<p>* script/dbconsole fires up the command-line database client. #102 [Steve Purcell]</p>
<p>* Fix bug where plugin init.rb files from frozen gem specs weren&#8217;t being run. (pjb3) [#122 state:resolved]</p>
<p>* Made the location of the routes file configurable with config.routes_configuration_file (Scott Fleckenstein) [#88]</p>
<p>* Rails Edge info returns the latest git commit hash [Francesc Esplugas]</p>
<p>* Added Rails.public_path to control where HTML and assets are expected to be loaded from (defaults to Rails.root + &#8220;/public&#8221;) #11581 [nicksieger]</p>
<p>* rake time:zones:local finds correct base utc offset for zones in the Southern Hemisphere [Geoff Buesing]</p>
<p>* Don&#8217;t require rails/gem_builder during rails initialization, it&#8217;s only needed for the gems:build task. [rick]</p>
<p>* script/performance/profiler compatibility with the ruby-prof &gt;= 0.5.0. Closes #9176. [Catfish]</p>
<p>* Flesh out rake gems:unpack to unpack all gems, and add rake gems:build for native extensions. #11513 [ddollar]</p>
<p>  rake gems:unpack # unpacks all gems<br />
  rake gems:unpack GEM=mygem # unpacks only the gem &#8216;mygem&#8217;</p>
<p>  rake gems:build # builds all unpacked gems<br />
  rake gems:build GEM=mygem # builds only the gem &#8216;mygem&#8217;</p>
<p>* Add config.active_support for future configuration options. Also, add more new Rails 3 config settings to new_rails_defaults.rb [rick]</p>
<p>* Add Rails.logger, Rails.root, Rails.env and Rails.cache shortcuts for RAILS_* constants [pratik]</p>
<p>* Allow files in plugins to be reloaded like the rest of the application. [rick]</p>
<p>  Enables or disables plugin reloading.</p>
<p>    config.reload_plugins = true</p>
<p>  You can get around this setting per plugin.<br />
  If #reload_plugins? == false (DEFAULT), add this to your plugin&#8217;s init.rb to make it reloadable:</p>
<p>    Dependencies.load_once_paths.delete lib_path</p>
<p>  If #reload_plugins? == true, add this to your plugin&#8217;s init.rb to only load it once:</p>
<p>    Dependencies.load_once_paths &lt; &#8220;openid&#8221;, :version =&gt; &#8220;1.1.4&#8243;<br />
  config.gem &#8220;ruby-yadis&#8221;, :lib =&gt; &#8220;yadis&#8221;, :version =&gt; &#8220;0.3.4&#8243;</p>
<p>  config.after_initialize do<br />
    ActionController::Base.send :include, OpenIdAuthentication<br />
  end</p>
<p>* Added config.gem for specifying which gems are required by the application, as well as rake tasks for installing and freezing gems. [rick]</p>
<p>  Rails::Initializer.run do |config|<br />
    config.gem &#8220;bj&#8221;<br />
    config.gem &#8220;hpricot&#8221;, :version =&gt; &#8216;0.6&#8242;, :source =&gt; &#8220;http://code.whytheluckystiff.net&#8221;<br />
    config.gem &#8220;aws-s3&#8243;, :lib =&gt; &#8220;aws/s3&#8243;<br />
  end</p>
<p>  # List required gems.<br />
  rake gems</p>
<p>  # Install all required gems:<br />
  rake gems:install</p>
<p>  # Unpack specified gem to vendor/gems/gem_name-x.x.x<br />
  rake gems:unpack GEM=bj</p>
<p>* Removed the default .htaccess configuration as there are so many good deployment options now (kept it as an example in README) [DHH]</p>
<p>* config.time_zone accepts TZInfo::Timezone identifiers as well as Rails TimeZone identifiers [Geoff Buesing]</p>
<p>* Rails::Initializer#initialize_time_zone raises an error if value assigned to config.time_zone is not recognized. Rake time zone tasks only require ActiveSupport instead of entire environment [Geoff Buesing]</p>
<p>* Stop adding the antiquated test/mocks/* directories and only add them to the path if they&#8217;re still there for legacy reasons [DHH]</p>
<p>* Added that gems can now be plugins if they include rails/init.rb #11444 [jbarnette]</p>
<p>* Added Plugin#about method to programmatically access the about.yml in a plugin #10979 [lazyatom]</p>
<p>    plugin = Rails::Plugin.new(path_to_my_plugin)<br />
    plugin.about["author"] # =&gt; &#8220;James Adam&#8221;<br />
    plugin.about["url"] # =&gt; &#8220;http://interblah.net&#8221;</p>
<p>* Improve documentation. [Radar, Jan De Poorter, chuyeow, xaviershay, danger, miloops, Xavier Noria, Sunny Ripert]</p>
<p>* Added config.time_zone = &#8216;UTC&#8217; in the default environment.rb [Geoff Buesing]</p>
<p>* Added rake tasks time:zones:all, time:zones:us and time:zones:local for finding time zone names for config.time_zone option [Geoff Buesing]</p>
<p>* Add config.time_zone for configuring the default Time.zone value. #10982 [Geoff Buesing]</p>
<p>* Added support for installing plugins hosted at git repositories #11294 [danger]</p>
<p>* Fixed that script/generate would not look for plugin generators in plugin_paths #11000 [glv]</p>
<p>* Fixed database rake tasks to work with charset/collation and show proper error messages on failure. Closes #11301 [matt]</p>
<p>* Added a -e/&#8211;export to script/plugin install, uses svn export. #10847 [jon@blankpad.net)]</p>
<p>* Reshuffle load order so that routes and observers are initialized after plugins and app initializers. Closes #10980 [rick]</p>
<p>* Git support for script/generate. #10690 [ssoroka]</p>
<p>* Update scaffold to use labels instead of bold tags. Closes #10757 [zach-inglis-lt3]</p>
<p>* Resurrect WordNet synonym lookups. #10710 [tom./, matt]</p>
<p>* Added config.cache_store to environment options to control the default cache store (default is FileStore if tmp/cache is present, otherwise MemoryStore is used) [DHH]</p>
<p>* Added that rails:update is run when you do rails:freeze:edge to ensure you also get the latest JS and config files #10565 [jeff]</p>
<p>* SQLite: db:drop:all doesn&#8217;t fail silently if the database is already open. #10577 [Cheah Chu Yeow, mrichman]</p>
<p>* Introduce native mongrel handler and push mutex into dispatcher. [Jeremy Kemper]</p>
<p>* Ruby 1.9 compatibility. #1689, #10546 [Cheah Chu Yeow, frederico]</p></blockquote>
<p>可以看到最下面这里有写着兼容Ruby1.9，另一个比较重大的特性就是Timezone的加入，另外还有对于Rails应用程序的依赖包的管理。其它都是小改动或者修补Bug。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/18/%e7%9c%8brails21%e7%9a%84changelog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shoulda教程翻译完了</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e7%bf%bb%e8%af%91%e5%ae%8c%e4%ba%86/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e7%bf%bb%e8%af%91%e5%ae%8c%e4%ba%86/#comments</comments>
		<pubDate>Sun, 18 May 2008 03:01:39 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Thinking]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e7%bf%bb%e8%af%91%e5%ae%8c%e4%ba%86/</guid>
		<description><![CDATA[终于把这个框架的文档翻译完了。最后一篇的缩进真是搞死我了，如果wp的编辑器更加强些就好了。

Shoulda：让Test::Unit也BDD
Shoulda教程之一—基本的should语句
Shoulda教程之二—上下文
Shoulda教程之三—测试ActiveRecord模型
Shoulda教程之四—测试控制器

其实看到Shoulda这个框架之后我会有很多思考，思考之前的BDD或TDD是不是太麻烦了，比如每次Fun Test都是要些mock Model，然后才能测试每次每次都是在重复，而每次页面的测试（Rspec里才有分离出来的测试）每次都要先构造出页面中要调用的对象，再assigns页面要调用到的元素之后再测试。整个过程非常繁琐，虽然这样可以很细粒度地测试到整个应用，但一点也不DRY（或许我的水平还不够）。
再抱怨一点，很多有名的Rails开源应用（如Beast，Redmind，Typo等等）很多都还未迁移到Rspec，虽然他们的项目目录中很多都有了spec这个目录，可是一般都是空的。想看到的Rspec的用于集成测试的Stroy框架的实例也没有，这个只能在教程中看到。Rspec的教程也太少，Rdoc中基本没有什么解释，代码里也是，如果对一些东西不知道怎么用就要去看代码，有些代码只是包装了Rails中的assist方法的还要去查Rails的方法代码（如果对Rails的一些assist不熟的话）。虽然这个过程可以看很多代码，学到更多，可是也太费时间了。
最后如果能把Shoulda的一些强大的宏移植到Rspec那就好了。当然，我会继续研究Shoulda源码，还要下一步要看看merb。
翻译完最后生成PDF在这里可以下载：http://download.csdn.net/source/458857
]]></description>
			<content:encoded><![CDATA[<p>终于把这个框架的文档翻译完了。最后一篇的缩进真是搞死我了，如果wp的编辑器更加强些就好了。</p>
<blockquote><p>
<a href="http://redworld.blog.ubuntu.org.cn/2008/05/03/shoulda%ef%bc%9a%e8%ae%a9testunit%e4%b9%9fbdd/">Shoulda：让Test::Unit也BDD</a></p>
<p><a href="http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b1/">Shoulda教程之一—基本的should语句</a></p>
<p><a href="http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b2/">Shoulda教程之二—上下文</a></p>
<p><a href="http://redworld.blog.ubuntu.org.cn/2008/05/11/shoulda%e6%95%99%e7%a8%8b3/">Shoulda教程之三—测试ActiveRecord模型</a></p>
<p><a href="http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b%e2%80%94%e6%b5%8b%e8%af%95%e6%8e%a7%e5%88%b6%e5%99%a8/">Shoulda教程之四—测试控制器</a>
</p></blockquote>
<p>其实看到Shoulda这个框架之后我会有很多思考，思考之前的BDD或TDD是不是太麻烦了，比如每次Fun Test都是要些mock Model，然后才能测试每次每次都是在重复，而每次页面的测试（Rspec里才有分离出来的测试）每次都要先构造出页面中要调用的对象，再assigns页面要调用到的元素之后再测试。整个过程非常繁琐，虽然这样可以很细粒度地测试到整个应用，但一点也不DRY（或许我的水平还不够）。</p>
<p>再抱怨一点，很多有名的Rails开源应用（如Beast，Redmind，Typo等等）很多都还未迁移到Rspec，虽然他们的项目目录中很多都有了spec这个目录，可是一般都是空的。想看到的Rspec的用于集成测试的Stroy框架的实例也没有，这个只能在教程中看到。Rspec的教程也太少，Rdoc中基本没有什么解释，代码里也是，如果对一些东西不知道怎么用就要去看代码，有些代码只是包装了Rails中的assist方法的还要去查Rails的方法代码（如果对Rails的一些assist不熟的话）。虽然这个过程可以看很多代码，学到更多，可是也太费时间了。</p>
<p>最后如果能把Shoulda的一些强大的宏移植到Rspec那就好了。当然，我会继续研究Shoulda源码，还要下一步要看看merb。</p>
<p>翻译完最后生成PDF在这里可以下载：http://download.csdn.net/source/458857</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e7%bf%bb%e8%af%91%e5%ae%8c%e4%ba%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shoulda教程之四—测试控制器</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b%e2%80%94%e6%b5%8b%e8%af%95%e6%8e%a7%e5%88%b6%e5%99%a8/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b%e2%80%94%e6%b5%8b%e8%af%95%e6%8e%a7%e5%88%b6%e5%99%a8/#comments</comments>
		<pubDate>Sun, 18 May 2008 02:02:02 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b%e2%80%94%e6%b5%8b%e8%af%95%e6%8e%a7%e5%88%b6%e5%99%a8/</guid>
		<description><![CDATA[控制器
基本的控制助手方法
如ActiveRecord宏一样，Shoulda 提供了一套测试控制器的宏，以尽可能简洁的方法进行测试。所有的这些方法都在Shoulda的Rdoc中，但这里再送上一个快捷的例子：

class UsersControllerTest &#60; Test::Unit::TestCase
&#160;&#160;context "on GET to :show" do
&#160;&#160;&#160;&#160;setup { get :show, :id =&#62; 1 }
&#160;&#160;
&#160;&#160;&#160;&#160;should_assign_to :user
&#160;&#160;&#160;&#160;should_respond_with :success
&#160;&#160;&#160;&#160;should_render_template :show
&#160;&#160;&#160;&#160;should_not_set_the_flash
&#160;&#160;
&#160;&#160;&#160;&#160;should "do something else really cool" do
&#160;&#160;&#160;&#160;&#160;&#160;assert_equal 1, assigns(:user).id
&#160;&#160;&#160;&#160;end
&#160;&#160;end
&#160;&#160;
&#160;&#160;context "on POST to :create" do
&#160;&#160;&#160;&#160;setup { post :create, :user =&#62; {:name =&#62; 'Ronald', :party =&#62; 'Repukeulan' } }
&#160;&#160;&#160;&#160;should_assign_to :user
&#160;&#160;&#160;&#160;should_redirect_to "user_url(@user)"
&#160;&#160;&#160;&#160;should_set_the_flash_to(/created/i)
&#160;&#160;end
end
应该RESTful
这里每个 should_xxx 宏都会产生一个单独的测试方法，编写起来又DRY。而should_be_restful 宏可以产生遵循基本的RESTful设计模式的控制器。should_be_restful 宏就像一个超级测试生成器，每次调用是都会产生40到50个测试方法。这里有个超简单的例子：
class UsersControllerTest &#60; Test::Unit::TestCase
&#160;&#160;def [...]]]></description>
			<content:encoded><![CDATA[<h1>控制器</h1>
<h2>基本的控制助手方法</h2>
<p>如ActiveRecord宏一样，Shoulda 提供了一套测试控制器的宏，以尽可能简洁的方法进行测试。所有的这些方法都在Shoulda的Rdoc中，但这里再送上一个快捷的例子：</p>
<pre><code>
class UsersControllerTest &lt; Test::Unit::TestCase
&nbsp;&nbsp;context "on GET to :show" do
&nbsp;&nbsp;&nbsp;&nbsp;setup { get :show, :id =&gt; 1 }
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;should_assign_to :user
&nbsp;&nbsp;&nbsp;&nbsp;should_respond_with :success
&nbsp;&nbsp;&nbsp;&nbsp;should_render_template :show
&nbsp;&nbsp;&nbsp;&nbsp;should_not_set_the_flash
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;should "do something else really cool" do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert_equal 1, assigns(:user).id
&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;context "on POST to :create" do
&nbsp;&nbsp;&nbsp;&nbsp;setup { post :create, :user =&gt; {:name =&gt; 'Ronald', :party =&gt; 'Repukeulan' } }
&nbsp;&nbsp;&nbsp;&nbsp;should_assign_to :user
&nbsp;&nbsp;&nbsp;&nbsp;should_redirect_to "user_url(@user)"
&nbsp;&nbsp;&nbsp;&nbsp;should_set_the_flash_to(/created/i)
&nbsp;&nbsp;end
end</code></pre>
<h2>应该RESTful</h2>
<p>这里每个 should_xxx 宏都会产生一个单独的测试方法，编写起来又DRY。而should_be_restful 宏可以产生遵循基本的RESTful设计模式的控制器。should_be_restful 宏就像一个超级测试生成器，每次调用是都会产生40到50个测试方法。这里有个超简单的例子：</p>
<pre><code>class UsersControllerTest &lt; Test::Unit::TestCase
&nbsp;&nbsp;def setup
&nbsp;&nbsp;&nbsp;&nbsp;@user = User.find(:first)
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;resource.create.params = { :name =&gt; "Billy Bumbler", :party =&gt; 'Sure do!'}
&nbsp;&nbsp;&nbsp;&nbsp;resource.update.params = { :name =&gt; "Changed" }
&nbsp;&nbsp;end
end</code></pre>
<p>这里会生成一整套包含全部CRUD行为的测试，也包括 :new 和 :edit 。对这个宏还有很多定义的空间，能让它处理各种情况的控制器，不过默认设置已经非常智能了。在上面的例子中，通过测试类名就能查找出如何处理User模型，users_url方法，params[:user]，@user 和@users实例变量等。</p>
<h3>配置should_be_restful</h3>
<p>来看看更改should-be_restful产生的测试的行为的方法。（这些也在Rdoc文档中有详细记录）</p>
<pre><code>class UsersControllerTest &lt; Test::Unit::TestCase
&nbsp;&nbsp;def setup
&nbsp;&nbsp;&nbsp;&nbsp;@user = User.find(:first)
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;resource.klass      = User
&nbsp;&nbsp;&nbsp;&nbsp;resource.object     = :user
&nbsp;&nbsp;&nbsp;&nbsp;resource.parent     = []
&nbsp;&nbsp;&nbsp;&nbsp;resource.actions    = [:index, :show, :new, :edit, :update, :create, :destroy]
&nbsp;&nbsp;&nbsp;&nbsp;resource.formats    = [:html, :xml]
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;resource.create.params = { :name =&gt; "bob", :email =&gt; 'bob@bob.com', :age =&gt; 13}
&nbsp;&nbsp;&nbsp;&nbsp;resource.update.params = { :name =&gt; "sue" }
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;resource.create.redirect  = "user_url(@user)"
&nbsp;&nbsp;&nbsp;&nbsp;resource.update.redirect  = "user_url(@user)"
&nbsp;&nbsp;&nbsp;&nbsp;resource.destroy.redirect = "users_url"
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;resource.create.flash  = /created/i
&nbsp;&nbsp;&nbsp;&nbsp;resource.update.flash  = /updated/i
&nbsp;&nbsp;&nbsp;&nbsp;resource.destroy.flash = /removed/i
&nbsp;&nbsp;end
end</code></pre>
<p>下面是参数的具体解释：</p>
<blockquote><p>    * klass：要处理的模型类。<br />
    * objuect：用于#edit，#update和#destroy测试的对象的名字。所以如果在setup中实例化@user，那么res.object 应该设置为 :user。<br />
    * parent：嵌套资源中的上级对象名字。这是要传入到嵌套资源url助手方法的参数。如果不需要用到嵌套资源，可以忽略这个参数。如果使用嵌套资源，路由设置中:users置于:cities之下，那么user测速中res.parent设置应为:city。实际上，parent参数是User模型类的关联对象引用。所以如果当User belongs_to :location，class_name =&gt; &#8220;City&#8221;，那么应该把这个参数设置为:city。<br />
    * actions：要测试的行为列表。这个值应该是[:index, :show, :new, :edit, :create, :update, :destroy]（默认）的子集或全集。如果控制器是read_only的，那么可能需要设置这个值为[:index, :show]。<br />
    * formats：测试控制器支持的格式列表。默认值为:html和 :xml，以后会加入JSON，CSV和其他。添加上其他的新格式也是非常简单的，可以参考ThoughtBot::Shoulda::Controller::XML文件。</p></blockquote>
<p>在#create，#update和#destory测试中可以附上一些参数：</p>
<blockquote><p>    * params：要传给行为的参数。<br />
    * flash：在行为完成之后在flash中预期得到的值。可以是字符串或者正则表达式。<br />
    * redirect：在行为完成之后应该重定向到方向。这里有些巧妙&#8230;在测试运行时才会解释设置的字符串。这个延后解析的字符串将会遍历所有的命名路由和所有控制器创建的实例变量。</p></blockquote>
<h3>Denied行为</h3>
<p>RESTful 控制器的部分或全部的行为在大多数场景里是有访问限制的（比如需要用户认证的时候）。resource.denied选项让should_be_restful原生地支持行为的访问限制。</p>
<pre><code>class UsersControllerTest &lt; Test::Unit::TestCase
&nbsp;&nbsp;def setup
&nbsp;&nbsp;@user = User.find(:first)
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;resource.create.params = { :name =&gt; "bob", :email =&gt; 'bob@bob.com', :age =&gt; 13}
&nbsp;&nbsp;&nbsp;&nbsp;resource.update.params = { :name =&gt; "sue" }
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.actions  = [:new, :create, :edit, :update, :destroy]
&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.redirect = "new_session_url"
&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.flash    = /administrator/i
&nbsp;&nbsp;end
end</code></pre>
<p>每个列在resource.denied.actions的行为（默认为空）将测试行为被限制访问，相关的记录不会被触及。 :redirect 和 :flash 参数和上面的 resource.create 和 resource.update 一样。</p>
<h3>混合使用should_be_restful和上下文</h3>
<p>测试每个控制器和所有控制器行为时，混合should_be_restful和上下文代码块是一个非常强大的方法。下面的代码是在我们（作者）的应用的测试中很常见到。</p>
<pre><code>class PostsControllerTest &lt; Test::Unit::TestCase
&nbsp;&nbsp;def setup
&nbsp;&nbsp;&nbsp;&nbsp;@user = users(:bob)
&nbsp;&nbsp;&nbsp;&nbsp;@post = @user.posts.first
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;context "An administrator" do
&nbsp;&nbsp;&nbsp;&nbsp;setup { login_as users(:admin) }
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.create.params = { :subject =&gt; "test", :body =&gt; "message" }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.update.params = { :subject =&gt; "changed" }
&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;context "A user" do
&nbsp;&nbsp;&nbsp;&nbsp;setup { login_as @user }
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.create.params = { :subject =&gt; "test", :body =&gt; "message" }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.update.params = { :subject =&gt; "changed" }
&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;context "A stranger" do
&nbsp;&nbsp;&nbsp;&nbsp;setup { login_as users(:sally) }
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.create.params   = { :subject =&gt; "test", :body =&gt; "message" }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.actions  = [:edit, :update, :destroy]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.redirect = "login_url"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.flash    = /only the owner can/i
&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;context "The public" do
&nbsp;&nbsp;&nbsp;&nbsp;setup { logout }
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.actions  = [:new, :create, :edit, :update, :destroy]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.redirect = "signup_url"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.denied.flash    = /must be a member/i
&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;end
end</code></pre>
<h3>混合与匹配</h3>
<p>最后，记住更好的测试在should_be_restful助手之外的额外行为，或者在Shoulda中加入一般的test_xxx方法。</p>
<pre><code>class UsersControllerTest &lt; Test::Unit::TestCase
&nbsp;&nbsp;def setup
&nbsp;&nbsp;&nbsp;&nbsp;@user = User.find
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;should_be_restful do |resource|
&nbsp;&nbsp;&nbsp;&nbsp;resource.create.params = { :name =&gt; "Billy Bumbler", :party =&gt; 'Sure do!'}
&nbsp;&nbsp;&nbsp;&nbsp;resource.update.params = { :name =&gt; "Changed" }
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;context "on GET to /users/:id;activate"
&nbsp;&nbsp;&nbsp;&nbsp;setup { get :activate, :id =&gt; @user.id }
&nbsp;&nbsp;&nbsp;&nbsp;should_render_template :activate
&nbsp;&nbsp;&nbsp;&nbsp;# etc.
&nbsp;&nbsp;end
&nbsp;&nbsp;
&nbsp;&nbsp;def test_normal_stuff
&nbsp;&nbsp;&nbsp;&nbsp;assert true
&nbsp;&nbsp;end
end</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/18/shoulda%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b%e2%80%94%e6%b5%8b%e8%af%95%e6%8e%a7%e5%88%b6%e5%99%a8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BEA JAVA2SOA DEV2DEV Techdays</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/14/bea-java2soa-dev2dev-techdays/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/14/bea-java2soa-dev2dev-techdays/#comments</comments>
		<pubDate>Wed, 14 May 2008 10:09:24 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/14/bea-java2soa-dev2dev-techdays/</guid>
		<description><![CDATA[


]]></description>
			<content:encoded><![CDATA[<p><img src="http://lh3.ggpht.com/chenk85/SCq44eDvyBI/AAAAAAAAACg/NRZLptA0tRA/SNV81056.JPG?imgmax=720" alt="" /></p>
<p><img src="http://lh5.ggpht.com/chenk85/SCq44-DvyCI/AAAAAAAAACo/m0VLYd_4JcE/SNV81057.JPG?imgmax=720" alt="" /></p>
<p><img src="http://lh3.ggpht.com/chenk85/SCq45eDvyDI/AAAAAAAAACw/krxRCgW1gy0/SNV81061.JPG?imgmax=720" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/14/bea-java2soa-dev2dev-techdays/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>持续集成de读书笔记</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/13/%e6%8c%81%e7%bb%ad%e9%9b%86%e6%88%90de%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/13/%e6%8c%81%e7%bb%ad%e9%9b%86%e6%88%90de%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0/#comments</comments>
		<pubDate>Mon, 12 May 2008 17:27:35 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Reading]]></category>
		<category><![CDATA[读书]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/13/%e6%8c%81%e7%bb%ad%e9%9b%86%e6%88%90de%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0/</guid>
		<description><![CDATA[五一的两天空余时间，读完了持续集成这本书。
Continuous Integration，持续集成，简称CI。这是一项业界推荐的软件开发实践，是XP中提到的实践之一。CI有四个特征：

与版本控制系统的连接
构建脚本
某种类型的反馈机制
集成源代码变更的过程


CI的价值在于：

减少风险
减少重复过程
在随时随地生成可部署的软件
对开发团队的软件产品建立起更大的产品信心


CI的步骤：
“I Build So Consistently”。四个步骤：“Identify”，“Build”，“Share”，“Continuous”。
CI的实践：
经常提交代码
不要提交无法构建的代码
立即修复无法集成的构建
编写自动化的开发者测试
必须通过所有测试和审查
执行私有构建
避免签出无法构建的代码
CI可以缓解一些关键的风险：
没有可部署的软件
很晚才发现缺陷
缺乏项目可见性
低品质的软件
CI系统的创建：
持续数据库集成
持续测试
持续审查
持续部署
持续反馈
Rails 的CI系统有来自TW的cruisecontrolrb
]]></description>
			<content:encoded><![CDATA[<p>五一的两天空余时间，读完了<a href="http://www.amazon.com/Continuous-Integration-Improving-Addison-Wesley-Signature/dp/0321336380/ref=sr_11_1?ie=UTF8&amp;qid=1200534624&amp;sr=11-1">持续集成</a>这本书。</p>
<p>Continuous Integration，持续集成，简称CI。这是一项业界推荐的软件开发实践，是XP中提到的实践之一。CI有四个特征：</p>
<blockquote><ol>
<li>与版本控制系统的连接</li>
<li>构建脚本</li>
<li>某种类型的反馈机制</li>
<li>集成源代码变更的过程</li>
</ol>
</blockquote>
<p>CI的价值在于：</p>
<blockquote><ol>
<li>减少风险</li>
<li>减少重复过程</li>
<li>在随时随地生成可部署的软件</li>
<li>对开发团队的软件产品建立起更大的产品信心</li>
</ol>
</blockquote>
<p>CI的步骤：</p>
<blockquote><p>“I Build So Consistently”。四个步骤：“Identify”，“Build”，“Share”，“Continuous”。</p></blockquote>
<p>CI的实践：</p>
<blockquote><p>经常提交代码<br />
不要提交无法构建的代码<br />
立即修复无法集成的构建<br />
编写自动化的开发者测试<br />
必须通过所有测试和审查<br />
执行私有构建<br />
避免签出无法构建的代码</p></blockquote>
<p>CI可以缓解一些关键的风险：</p>
<blockquote><p>没有可部署的软件<br />
很晚才发现缺陷<br />
缺乏项目可见性<br />
低品质的软件</p></blockquote>
<p>CI系统的创建：</p>
<blockquote><p>持续数据库集成<br />
持续测试<br />
持续审查<br />
持续部署<br />
持续反馈</p></blockquote>
<p>Rails 的CI系统有来自TW的<a href="http://cruisecontrolrb.thoughtworks.com/">cruisecontrolrb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/13/%e6%8c%81%e7%bb%ad%e9%9b%86%e6%88%90de%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails2.1新特性之ActiveRecord::Base.create的变化</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bactiverecordbasecreate%e7%9a%84%e5%8f%98%e5%8c%96/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bactiverecordbasecreate%e7%9a%84%e5%8f%98%e5%8c%96/#comments</comments>
		<pubDate>Mon, 12 May 2008 15:45:52 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bactiverecordbasecreate%e7%9a%84%e5%8f%98%e5%8c%96/</guid>
		<description><![CDATA[ActiveRecord::Base.create 现在可以像 ActiveRecord::Base.new 一样带上一个代码块参数了。
@person = Person.create(params[:person]) do &#124;p&#124;
 p.name = 'Konata Izumi'
 p.age = 17
end
]]></description>
			<content:encoded><![CDATA[<p>ActiveRecord::Base.create 现在可以像 ActiveRecord::Base.new 一样带上一个代码块参数了。</p>
<p><code>@person = Person.create(params[:person]) do |p|<br />
 p.name = 'Konata Izumi'<br />
 p.age = 17<br />
end</code></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bactiverecordbasecreate%e7%9a%84%e5%8f%98%e5%8c%96/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails2.1新特性之新的migrations方法change_table</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8b%e6%96%b0%e7%9a%84migrations%e6%96%b9%e6%b3%95change_table/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8b%e6%96%b0%e7%9a%84migrations%e6%96%b9%e6%b3%95change_table/#comments</comments>
		<pubDate>Mon, 12 May 2008 15:43:09 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8b%e6%96%b0%e7%9a%84migrations%e6%96%b9%e6%b3%95change_table/</guid>
		<description><![CDATA[原文：http://blog.codefront.net/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/
现在可以通过 change_table 代码块来完成对数据库表的修改。
change_table :videos do &#124;t&#124;
&#160;t.add_timestamps
&#160;t.add_belongs_to :goat
&#160;t.add_string :name, :email, :limit =&#62; 20
&#160;t.remove_column :name, :email # takes multiple arguments
&#160;t.rename :new_name
&#160;t.string :new_string_column # executes against the renamed table name
end
补充些要注意的事情：
    * add_XXX 方法会添加一个新列，比如 add_string 会添加一个新的 string 类型的字段。
    * Of course, add_timestamps 会添加神奇的 created_at 和 updated_at 的 datetime 类型的字段。
    * [...]]]></description>
			<content:encoded><![CDATA[<p>原文：http://blog.codefront.net/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/</p>
<p>现在可以通过 change_table 代码块来完成对数据库表的修改。</p>
<p><code>change_table :videos do |t|<br />
&nbsp;t.add_timestamps<br />
&nbsp;t.add_belongs_to :goat<br />
&nbsp;t.add_string :name, :email, :limit =&gt; 20<br />
&nbsp;t.remove_column :name, :email # takes multiple arguments<br />
&nbsp;t.rename :new_name<br />
&nbsp;t.string :new_string_column # executes against the renamed table name<br />
end</code></p>
<p>补充些要注意的事情：</p>
<p>    * add_XXX 方法会添加一个新列，比如 add_string 会添加一个新的 string 类型的字段。<br />
    * Of course, add_timestamps 会添加神奇的 created_at 和 updated_at 的 datetime 类型的字段。<br />
    * remove_column 现在可以接受多个参数。<br />
    * rename 方法会重命名数据库表。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8b%e6%96%b0%e7%9a%84migrations%e6%96%b9%e6%b3%95change_table/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails2.1新特性之script/dbconsole</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bscriptdbconsole/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bscriptdbconsole/#comments</comments>
		<pubDate>Mon, 12 May 2008 15:23:30 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bscriptdbconsole/</guid>
		<description><![CDATA[原文连接：http://blog.codefront.net/2008/05/11/living-on-the-edge-of-rails-20-scriptdbconsole-and-flashnow-now-test-able/
script/dbconsole 脚本允许用户使用Rails的控制台客户端连接到数据库。
如果需要连接到MySQL的生产数据库作一些操作，直接运行 RAILS_ENV=production script/dbconsole 就能登录到数据库服务器上并使用MySQL的命令行客户端。当然，这个脚本也同样在 PostgreSQL 和 SQLite 数据库运行。
要在当前Rails应用程序中使用这个新脚本，就要先升级到edge Rails，再运行 rake rails:update:script 。好好享受这个脚本的便利吧。
]]></description>
			<content:encoded><![CDATA[<p>原文连接：http://blog.codefront.net/2008/05/11/living-on-the-edge-of-rails-20-scriptdbconsole-and-flashnow-now-test-able/</p>
<p>script/dbconsole 脚本允许用户使用Rails的控制台客户端连接到数据库。</p>
<p>如果需要连接到MySQL的生产数据库作一些操作，直接运行 RAILS_ENV=production script/dbconsole 就能登录到数据库服务器上并使用MySQL的命令行客户端。当然，这个脚本也同样在 PostgreSQL 和 SQLite 数据库运行。</p>
<p>要在当前Rails应用程序中使用这个新脚本，就要先升级到edge Rails，再运行 rake rails:update:script 。好好享受这个脚本的便利吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/12/rails21%e6%96%b0%e7%89%b9%e6%80%a7%e4%b9%8bscriptdbconsole/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shoulda教程之三&#8212;测试ActiveRecord模型</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/11/shoulda%e6%95%99%e7%a8%8b3/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/11/shoulda%e6%95%99%e7%a8%8b3/#comments</comments>
		<pubDate>Sun, 11 May 2008 05:28:37 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/11/shoulda%e6%95%99%e7%a8%8b3/</guid>
		<description><![CDATA[ActiveRecord助手方法
Shoulda具有一套ActiveRecord测试宏，这让开发效率大大提高，TDD变得轻而易举。关于这个方面的所有的文档都在Shoulda的Rdoc中。下面就来个小小的例子：
class UserTest  :dogs
&#160;should_belong_to :lover
end
上面的代码创建了如下的测试：

test: Person should allow phone_number to be set to &#8220;(123) 456-7890&#8243;.
test: Person should belong to lover.
test: Person should have many dogs.
test: Person should have many messes through dogs.
test: Person should have one profile.
test: Person should not allow admin to be changed by update.
test: Person should not allow phone_number to be set [...]]]></description>
			<content:encoded><![CDATA[<h1>ActiveRecord助手方法</h1>
<p>Shoulda具有一套ActiveRecord测试宏，这让开发效率大大提高，TDD变得轻而易举。关于这个方面的所有的文档都在Shoulda的Rdoc中。下面就来个小小的例子：</p>
<p><code>class UserTest  :dogs<br />
&nbsp;should_belong_to :lover<br />
end</code></p>
<p>上面的代码创建了如下的测试：</p>
<blockquote><p>
test: Person should allow phone_number to be set to &#8220;(123) 456-7890&#8243;.<br />
test: Person should belong to lover.<br />
test: Person should have many dogs.<br />
test: Person should have many messes through dogs.<br />
test: Person should have one profile.<br />
test: Person should not allow admin to be changed by update.<br />
test: Person should not allow phone_number to be set to &#8220;1234&#8243;.<br />
test: Person should not allow phone_number to be set to &#8220;abcd&#8221;.<br />
test: Person should require name to be set.<br />
test: Person should require phone_number to be set.<br />
test: Person should require unique value for name.</p></blockquote>
<h2>前提</h2>
<p>一件需要知道的事情是一些ActiveRecord测试宏找到第一个初始的记录(通过 Class.find(:first))。你可以让这个工作通过一个具有一条记录的fixture文件，或者通过在setup中创建一条记录，类似下面这样：</p>
<p><code>class UserTest &lt; Test::Unit::TestCase<br />
&nbsp;def setup<br />
&nbsp;&nbsp;@user = User.create!(params)<br />
&nbsp;end<br />
&nbsp;<br />
&nbsp;should_require_unique_attributes :name<br />
end</code></p>
<p>或者通过一个context，如下：</p>
<p><code>class UserTest &lt; Test::Unit::TestCase<br />
&nbsp;context "given an existing record" do<br />
&nbsp;&nbsp;setup do<br />
&nbsp;&nbsp;&nbsp;@user = User.create!(params)<br />
&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;should_require_unique_attributes :name<br />
&nbsp;end<br />
end</code></p>
<p>但是Shoulda不止是提供了对模型的测试，还提供了很多强大的助手方法可以使用于控制器。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/11/shoulda%e6%95%99%e7%a8%8b3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shoulda教程之二&#8212;上下文</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b2/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b2/#comments</comments>
		<pubDate>Sat, 10 May 2008 08:47:48 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b2/</guid>
		<description><![CDATA[原文：http://thoughtbot.com/projects/shoulda/tutorial/context
上下文
在学习了Should语句之后，Shoulda的更多基本构建代码的知识就是上下文(Context)。上下文创建一个运行should语句的类似场景的fixture。Context代码块可以包含 setup/teardown 代码块，should代码块，或者其他context代码块。下面来试试在测试中使用简单的context：
class QueueTest &#60; Test::Unit::TestCase
&#160;context "一个队列实例" do
&#160;&#160;setup do
&#160;&#160;&#160;@queue = Queue.new
&#160;&#160;end
&#160;
&#160;&#160;should "响应 :push 调用" do
&#160;&#160;&#160;assert_respond_to @queue, :push
&#160;&#160;end
&#160;end
end
这里创建了一个名为&#8221;测试：一个队列实例可以响应:push调用&#8221;的测试方法，这很漂亮和易读。
嵌套
上面详尽的测试，简单测试队列的实例响应:push调用，但也提出了更多的上下文和测试。现在想看看让队列返回任何放进其中的东西。来添加一个嵌套的上下文进到其中：
class QueueTest &#60; Test::Unit::TestCase
&#160;context "一个队列实例" do
&#160;&#160;setup do
&#160;&#160;&#160;@queue = Queue.new
&#160;&#160;end
&#160;
&#160;&#160;should "响应 :push 调用" do
&#160;&#160;&#160;assert_respond_to @queue, :push
&#160;&#160;end
&#160;
&#160;&#160;context "具有一个元素" do
&#160;&#160;&#160;setup { @queue.push(:something) }
&#160;
&#160;&#160;&#160;should "在:pop调用后返回元素" do
&#160;&#160;&#160;&#160;assert_equal :something, @queue.pop
&#160;&#160;&#160;end
&#160;&#160;end
&#160;end
end
上面生成了测试方法&#8221;测试：一个队列实例应该响应:push调用&#8221;和&#8221;测试：一个队列实例具有一个元素应该在:pop调用后返回元素&#8221;。
注意一下，上下文的setup代码块是为每个should代码块运行一次的。首先@queue实例被创建出来，然后:something被放进去，接着执行assert_equal。下面用一个同样语意的测试方法虚拟地演示一下，记住下面的代码只是为了帮助理解，并不会实际的发生：
define_method "测试：一个队列实例有一个元素应该在:pop调用后返回元素。" do
&#160;@queue = Queue.new
&#160;@queue.push(:something)
&#160;assert_equal :something, @queue.pop
end
现在，如果使用一般的测试风格，就会在一个测试方法中，把一个元素放进队列中并在一个测试方法中把元素取出来，然后进行断言。但是将这个测试分离出来放到一个测试push的上下文时，就可以添加更多的共享同样setup的测试。
class QueueTest &#60; Test::Unit::TestCase
&#160;context "一个队列实例" do
&#160;&#160;setup do
&#160;&#160;&#160;@queue = Queue.new
&#160;&#160;end
&#160;
&#160;&#160;should "响应 [...]]]></description>
			<content:encoded><![CDATA[<p>原文：http://thoughtbot.com/projects/shoulda/tutorial/context</p>
<h1>上下文</h1>
<p>在学习了Should语句之后，Shoulda的更多基本构建代码的知识就是上下文(Context)。上下文创建一个运行should语句的类似场景的fixture。Context代码块可以包含 setup/teardown 代码块，should代码块，或者其他context代码块。下面来试试在测试中使用简单的context：</p>
<p><code>class QueueTest &lt; Test::Unit::TestCase<br />
&nbsp;context "一个队列实例" do<br />
&nbsp;&nbsp;setup do<br />
&nbsp;&nbsp;&nbsp;@queue = Queue.new<br />
&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;should "响应 :push 调用" do<br />
&nbsp;&nbsp;&nbsp;assert_respond_to @queue, :push<br />
&nbsp;&nbsp;end<br />
&nbsp;end<br />
end</code></p>
<p>这里创建了一个名为&#8221;测试：一个队列实例可以响应:push调用&#8221;的测试方法，这很漂亮和易读。</p>
<h2>嵌套</h2>
<p>上面详尽的测试，简单测试队列的实例响应:push调用，但也提出了更多的上下文和测试。现在想看看让队列返回任何放进其中的东西。来添加一个嵌套的上下文进到其中：</p>
<p><code>class QueueTest &lt; Test::Unit::TestCase<br />
&nbsp;context "一个队列实例" do<br />
&nbsp;&nbsp;setup do<br />
&nbsp;&nbsp;&nbsp;@queue = Queue.new<br />
&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;should "响应 :push 调用" do<br />
&nbsp;&nbsp;&nbsp;assert_respond_to @queue, :push<br />
&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;context "具有一个元素" do<br />
&nbsp;&nbsp;&nbsp;setup { @queue.push(:something) }<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;should "在:pop调用后返回元素" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;assert_equal :something, @queue.pop<br />
&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
&nbsp;end<br />
end</code></p>
<p>上面生成了测试方法&#8221;测试：一个队列实例应该响应:push调用&#8221;和&#8221;测试：一个队列实例具有一个元素应该在:pop调用后返回元素&#8221;。</p>
<p>注意一下，上下文的setup代码块是为每个should代码块运行一次的。首先@queue实例被创建出来，然后:something被放进去，接着执行assert_equal。下面用一个同样语意的测试方法虚拟地演示一下，记住下面的代码只是为了帮助理解，并不会实际的发生：</p>
<p><code>define_method "测试：一个队列实例有一个元素应该在:pop调用后返回元素。" do<br />
&nbsp;@queue = Queue.new<br />
&nbsp;@queue.push(:something)<br />
&nbsp;assert_equal :something, @queue.pop<br />
end</code></p>
<p>现在，如果使用一般的测试风格，就会在一个测试方法中，把一个元素放进队列中并在一个测试方法中把元素取出来，然后进行断言。但是将这个测试分离出来放到一个测试push的上下文时，就可以添加更多的共享同样setup的测试。</p>
<p><code>class QueueTest &lt; Test::Unit::TestCase<br />
&nbsp;context "一个队列实例" do<br />
&nbsp;&nbsp;setup do<br />
&nbsp;&nbsp;&nbsp;@queue = Queue.new<br />
&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;should "响应 :push 调用" do<br />
&nbsp;&nbsp;&nbsp;assert_respond_to @queue, :push<br />
&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;context "具有一个元素" do<br />
&nbsp;&nbsp;&nbsp;setup { @queue.push(:something) }<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;should "在:pop调用后返回元素" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;assert_equal :something, @queue.pop<br />
&nbsp;&nbsp;&nbsp;end<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;should "在:size调用后返回1" do<br />
&nbsp;&nbsp;&nbsp;&nbsp;assert_equal 1, @queue.size<br />
&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
&nbsp;end<br />
end</code></p>
<p>在让测试保持可读性和防止重复代码方面，嵌套的上下文是一个强大的工具。测试文件变得更大时，更多的这种重构就会起作用。</p>
<h2>在setup中断言</h2>
<p>另一个美妙的setup代码块的特性是，可以运行一部分测试方法，也就是可以完美地把断言放在其中。在setup代码块中调用断言来代替在should代码块中断言，并不是一个非常好的做法，但是可以起到一个明确的检查作用。来个例子：</p>
<p><code>class PersonTest &lt; Test::Unit::TestCase<br />
&nbsp;context "A Person" do<br />
&nbsp;&nbsp;setup { assert @person = Person.find(:first) }<br />
&nbsp;<br />
&nbsp;&nbsp;should "rock out" do<br />
&nbsp;&nbsp;&nbsp;assert @person.rocks_out!<br />
&nbsp;&nbsp;end<br />
&nbsp;end<br />
end</code></p>
<p>在find调用失败时，在setup中看到失败的断言比出现烦人的异常要好看多了。</p>
<p>should代码块和上下文是为测试宏(test macros)不错的起点。Shoulda还有一个ActiveRecord助手方法集合，让测试简明扼要。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shoulda教程之一&#8212;基本的should语句</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b1/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b1/#comments</comments>
		<pubDate>Sat, 10 May 2008 07:06:31 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b1/</guid>
		<description><![CDATA[原文：http://thoughtbot.com/projects/shoulda/tutorial/should
Should 语句
Should语句是一种简洁，优雅，高可读性的方式创建测试。Should语句能轻松地创建测试方法，所以完全向后兼容一般的Test::Unit 用法
class QuoteTest &#60; Test::Unit::TestCase
&#160;def setup
&#160;&#160;# 和一般的Test::Unit一样
&#160;end
&#160;
&#160;def test_should_be_true
&#160;&#160;assert true
&#160;end
&#160;
&#160;should "为真" do
&#160;&#160;assert true
&#160;end
end

以上的代码片断创建了两个测试方法:&#8221;测试: 应该为真&#8221;和test_should_be_true。在这个级别，两个方法只有名字不同。一旦你学习有关Contexts的知识，就可以找到一些非常有用的技巧。
]]></description>
			<content:encoded><![CDATA[<p>原文：http://thoughtbot.com/projects/shoulda/tutorial/should</p>
<h1>Should 语句</h1>
<p>Should语句是一种简洁，优雅，高可读性的方式创建测试。Should语句能轻松地创建测试方法，所以完全向后兼容一般的Test::Unit 用法</p>
<p><code>class QuoteTest &lt; Test::Unit::TestCase<br />
&nbsp;def setup<br />
&nbsp;&nbsp;# 和一般的Test::Unit一样<br />
&nbsp;end<br />
&nbsp;<br />
&nbsp;def test_should_be_true<br />
&nbsp;&nbsp;assert true<br />
&nbsp;end<br />
&nbsp;<br />
&nbsp;should "为真" do<br />
&nbsp;&nbsp;assert true<br />
&nbsp;end<br />
end<br />
</code></p>
<p>以上的代码片断创建了两个测试方法:&#8221;测试: 应该为真&#8221;和test_should_be_true。在这个级别，两个方法只有名字不同。一旦你学习有关Contexts的知识，就可以找到一些非常有用的技巧。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/10/shoulda%e6%95%99%e7%a8%8b1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apriori算法的Ruby实现</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/10/apriori%e7%ae%97%e6%b3%95%e7%9a%84ruby%e5%ae%9e%e7%8e%b0/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/10/apriori%e7%ae%97%e6%b3%95%e7%9a%84ruby%e5%ae%9e%e7%8e%b0/#comments</comments>
		<pubDate>Sat, 10 May 2008 05:13:14 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/10/apriori%e7%ae%97%e6%b3%95%e7%9a%84ruby%e5%ae%9e%e7%8e%b0/</guid>
		<description><![CDATA[Apriori的算法实现，上课用到了。老师从网上找了一个300多行代码的Ruby实现，太复杂了，改了一下，太麻烦，自己重写过。
下面是实现代码

#!/usr/bin/ruby -w
# Apriori 算法实现
&#160;
class Apriori
attr_accessor :date_set, :min_sup, :lv1_item_set
&#160;
# 从指定文件中得到整个事务集
def get_data_set(input_file)
&#160;raise "Error: File #{input_file} does not exist" unless File.exists?(input_file)
&#160;content = ''
&#160;open(input_file) {&#124;f&#124; content = f.read}
&#160;content.inject([]) {&#124;set, l&#124; set &#60;= item.size
&#160;&#160;&#160;@lv1_item_set.each do &#124;i1&#124; # 第一级项集
&#160;&#160;&#160;&#160;if (item &#124; i1).size &#62; item.size &#38;&#38; intersection?(date, (item &#124; i1))
 &#160;&#160;&#160;&#160;&#160;candidacy_set.push((item &#124; i1).sort).uniq!  # 候选集生成
&#160;&#160;&#160;&#160;end
&#160;&#160;&#160;end
&#160;&#160;end
&#160;end
&#160;end
&#160;candidacy_set.sort
end
&#160;
# 从候选集产生频繁集
def create_frequent_item_set(candidacy_set)
&#160;frequent_item_set = Hash.new(0)
&#160;candidacy_set.each do &#124;e&#124;
&#160;&#160;@date_set.each [...]]]></description>
			<content:encoded><![CDATA[<p>Apriori的算法实现，上课用到了。老师从网上找了一个300多行代码的Ruby实现，太复杂了，改了一下，太麻烦，自己重写过。</p>
<p>下面是实现代码<br />
<span id="more-82"></span><br />
<code>#!/usr/bin/ruby -w<br />
# Apriori 算法实现<br />
&nbsp;<br />
class Apriori<br />
attr_accessor :date_set, :min_sup, :lv1_item_set<br />
&nbsp;<br />
# 从指定文件中得到整个事务集<br />
def get_data_set(input_file)<br />
&nbsp;raise "Error: File #{input_file} does not exist" unless File.exists?(input_file)<br />
&nbsp;content = ''<br />
&nbsp;open(input_file) {|f| content = f.read}<br />
&nbsp;content.inject([]) {|set, l| set &lt;= item.size<br />
&nbsp;&nbsp;&nbsp;@lv1_item_set.each do |i1| # 第一级项集<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (item | i1).size &gt; item.size &amp;&amp; intersection?(date, (item | i1))<br />
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;candidacy_set.push((item | i1).sort).uniq!  # 候选集生成<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
&nbsp;end<br />
&nbsp;end<br />
&nbsp;candidacy_set.sort<br />
end<br />
&nbsp;<br />
# 从候选集产生频繁集<br />
def create_frequent_item_set(candidacy_set)<br />
&nbsp;frequent_item_set = Hash.new(0)<br />
&nbsp;candidacy_set.each do |e|<br />
&nbsp;&nbsp;@date_set.each { |date| frequent_item_set[e] += 1 if intersection?(date, e)}<br />
&nbsp;end<br />
&nbsp;return frequent_item_set.delete_if {|k, v| v = @min_sup }<br />
  # 输出第一级项集<br />
  open(output_file, "w") do |f|<br />
    @lv1_item_set.each { |e| f.puts e + " : " + @hash[e].to_s }<br />
  end<br />
  # 迭代生成候选集<br />
  result = []<br />
  until(result.empty?) do<br />
    # ......<br />
  end<br />
end<br />
end</code></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/10/apriori%e7%ae%97%e6%b3%95%e7%9a%84ruby%e5%ae%9e%e7%8e%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shoulda：让Test::Unit也BDD</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/03/shoulda%ef%bc%9a%e8%ae%a9testunit%e4%b9%9fbdd/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/03/shoulda%ef%bc%9a%e8%ae%a9testunit%e4%b9%9fbdd/#comments</comments>
		<pubDate>Sat, 03 May 2008 11:19:46 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/03/shoulda%ef%bc%9a%e8%ae%a9testunit%e4%b9%9fbdd/</guid>
		<description><![CDATA[Shoulda是一个Rails插件，一个让Test::Unit也BDD的框架。这是官方的广告语：
Shoulda – Making tests easy on the fingers and eyes
我是在MountainWest RubyConf 2008的视频看到Tammer Saleh 讲了Shoulda才知道这个框架的：
http://mwrc2008.confreaks.com/12saleh.html
下面是官方资料的一点翻译：
Shoulda Rails插件能让你轻松地写出优雅，易懂，易维护的测试。Shoulda 包含了添加到了Test::Unit框架的宏，断言和助手方法。不需重新编写测试，完全适合已有的测试。
助手方法 – context方法和should方法使用了类似Rspec的测试块语法。还有，内置的contexts和一种可读性极强的语法。
宏 – 通过强大的宏生成上百行Controller和ActiveRecord测试。能让你快速开始，确保应用程序遵循最佳实践。
断言 – 许多一般的Rails测试惯用法提取了一个好用的断言集合。
也有一个精简的Shoulda的Gem包适合非Rails应用。
以后应该会继续翻译下去的。
Shoulda 官方主页
Shoulda 的RDocs
]]></description>
			<content:encoded><![CDATA[<p>Shoulda是一个Rails插件，一个让Test::Unit也BDD的框架。这是官方的广告语：</p>
<blockquote><p>Shoulda – Making tests easy on the fingers and eyes</p></blockquote>
<p>我是在MountainWest RubyConf 2008的视频看到Tammer Saleh 讲了Shoulda才知道这个框架的：<br />
<a href="http://mwrc2008.confreaks.com/12saleh.html">http://mwrc2008.confreaks.com/12saleh.html</a></p>
<p>下面是官方资料的一点翻译：</p>
<p>Shoulda Rails插件能让你轻松地写出优雅，易懂，易维护的测试。Shoulda 包含了添加到了Test::Unit框架的宏，断言和助手方法。不需重新编写测试，完全适合已有的测试。</p>
<p>助手方法 – context方法和should方法使用了类似Rspec的测试块语法。还有，内置的contexts和一种可读性极强的语法。</p>
<p>宏 – 通过强大的宏生成上百行Controller和ActiveRecord测试。能让你快速开始，确保应用程序遵循最佳实践。</p>
<p>断言 – 许多一般的Rails测试惯用法提取了一个好用的断言集合。</p>
<p>也有一个精简的Shoulda的Gem包适合非Rails应用。</p>
<p>以后应该会继续翻译下去的。</p>
<p><a href="http://www.thoughtbot.com/projects/shoulda">Shoulda 官方主页</a><br />
<a href="http://dev.thoughtbot.com/shoulda">Shoulda 的RDocs</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/03/shoulda%ef%bc%9a%e8%ae%a9testunit%e4%b9%9fbdd/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rails 2.1 RC释出</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/01/rails-21-rc%e9%87%8a%e5%87%ba/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/01/rails-21-rc%e9%87%8a%e5%87%ba/#comments</comments>
		<pubDate>Thu, 01 May 2008 10:17:55 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[something]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/01/rails-21-rc%e9%87%8a%e5%87%ba/</guid>
		<description><![CDATA[Rails的发展速度实在是快，这很好，只是千千万万的用户们要跟随着学习新特性，适应新的变化。教程和书籍也跟不上它的开发速度。
http://weblog.rubyonrails.com/2008/4/30/rails-2-1-release-candidate-is-imminent
]]></description>
			<content:encoded><![CDATA[<p>Rails的发展速度实在是快，这很好，只是千千万万的用户们要跟随着学习新特性，适应新的变化。教程和书籍也跟不上它的开发速度。</p>
<p>http://weblog.rubyonrails.com/2008/4/30/rails-2-1-release-candidate-is-imminent</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/01/rails-21-rc%e9%87%8a%e5%87%ba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>翻译Arch wiki上的wicd页</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/01/%e7%bf%bb%e8%af%91arch-wiki%e4%b8%8a%e7%9a%84wicd%e9%a1%b5/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/01/%e7%bf%bb%e8%af%91arch-wiki%e4%b8%8a%e7%9a%84wicd%e9%a1%b5/#comments</comments>
		<pubDate>Thu, 01 May 2008 07:21:53 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/01/%e7%bf%bb%e8%af%91arch-wiki%e4%b8%8a%e7%9a%84wicd%e9%a1%b5/</guid>
		<description><![CDATA[早上翻译了下面这页：
http://wiki.archlinux.org/index.php/Wicd
其中过程,FF3忽然崩溃，又要翻译多一次，其实里面还有点还没有翻译完。。。
终于为ArchLinux做出了点贡献。
]]></description>
			<content:encoded><![CDATA[<p>早上翻译了下面这页：<br />
http://wiki.archlinux.org/index.php/Wicd</p>
<p>其中过程,FF3忽然崩溃，又要翻译多一次，其实里面还有点还没有翻译完。。。</p>
<p>终于为ArchLinux做出了点贡献。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/01/%e7%bf%bb%e8%af%91arch-wiki%e4%b8%8a%e7%9a%84wicd%e9%a1%b5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rspec的Stroy框架</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/05/01/rspec%e7%9a%84stroy%e6%a1%86%e6%9e%b6/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/05/01/rspec%e7%9a%84stroy%e6%a1%86%e6%9e%b6/#comments</comments>
		<pubDate>Wed, 30 Apr 2008 16:46:57 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/05/01/rspec%e7%9a%84stroy%e6%a1%86%e6%9e%b6/</guid>
		<description><![CDATA[Stroy框架是一个在应用程序级别对测试进行描述的框架。Rspec的BDD测试中其实缺少了一个像Rails传统测试中的集成测试（integration tests）那样的东西，Rspec::Strop就是为了补上这个部分而产生的。
Stroy格式：
Title (故事标题)
&#160;
故事的描述:
作为一个怎样的角色
我想要什么样
最后得到怎样的结果
&#160;
验证故事的标准: (以场景(Scenario)的形式提出)
&#160;
Scenario: 场景标题
Given [场景内容]
&#160;&#160;And [场景附加内容]…
When  [发生事件]
Then  [产生的后果]
&#160;&#160;And [其它后果]…
&#160;
Scenario: …
以上就是故事编写的基本结构，Given后可以加多个And，Then也是。故事直接保存为文本文件就可以了。然后开始编写故事的验证机制（其实就是针对上面描述的场景以代码来表示）。

故事验证格式：
steps_for(:故事名)  do
&#160;&#160;Given("场景内容") do &#124;占位符&#124;
&#160;&#160;&#160;&#160;代码描述
&#160;&#160;end
&#160;&#160;When("发生事件") do &#124;占位符&#124;
&#160;&#160;&#160;&#160;代码描述
&#160;&#160;end
&#160;&#160;Then("产生的后果") do &#124;占位符&#124;
&#160;&#160;&#160;&#160;代码描述
&#160;&#160;end
end

解释下，Given块的个数应该与故事清单中的Given语句加后面的And的个数相当，Then块也是。
例子：
故事login
Story: 以存在的用户身份登录
    作为一个未认证的用户
    我想要登录到网站
    那么我能看见我的账户信息
&#160;&#160;
    Scenario: 正常登录
        Given 我的账户为test@example.org
        [...]]]></description>
			<content:encoded><![CDATA[<p>Stroy框架是一个在应用程序级别对测试进行描述的框架。Rspec的BDD测试中其实缺少了一个像Rails传统测试中的集成测试（integration tests）那样的东西，Rspec::Strop就是为了补上这个部分而产生的。</p>
<p>Stroy格式：<br />
<code>Title (故事标题)<br />
&nbsp;<br />
故事的描述:<br />
作为一个怎样的角色<br />
我想要什么样<br />
最后得到怎样的结果<br />
&nbsp;<br />
验证故事的标准: (以场景(Scenario)的形式提出)<br />
&nbsp;<br />
Scenario: 场景标题<br />
Given [场景内容]<br />
&nbsp;&nbsp;And [场景附加内容]…<br />
When  [发生事件]<br />
Then  [产生的后果]<br />
&nbsp;&nbsp;And [其它后果]…<br />
&nbsp;<br />
Scenario: …</code></p>
<p>以上就是故事编写的基本结构，Given后可以加多个And，Then也是。故事直接保存为文本文件就可以了。然后开始编写故事的验证机制（其实就是针对上面描述的场景以代码来表示）。<br />
<span id="more-77"></span><br />
故事验证格式：<br />
<code>steps_for(:故事名)  do<br />
&nbsp;&nbsp;Given("场景内容") do |占位符|<br />
&nbsp;&nbsp;&nbsp;&nbsp;代码描述<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;When("发生事件") do |占位符|<br />
&nbsp;&nbsp;&nbsp;&nbsp;代码描述<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;Then("产生的后果") do |占位符|<br />
&nbsp;&nbsp;&nbsp;&nbsp;代码描述<br />
&nbsp;&nbsp;end<br />
end<br />
</code><br />
解释下，Given块的个数应该与故事清单中的Given语句加后面的And的个数相当，Then块也是。</p>
<p>例子：<br />
故事login<br />
<code>Story: 以存在的用户身份登录<br />
    作为一个未认证的用户<br />
    我想要登录到网站<br />
    那么我能看见我的账户信息<br />
&nbsp;&nbsp;<br />
    Scenario: 正常登录<br />
        Given 我的账户为test@example.org<br />
        When 我用邮箱为test@example.org和密码是foofoo进行登录<br />
        Then 我能够登录<br />
        And 我会看到账户页面</code><br />
故事验证login.rb：<br />
<code>require 'rubygems'<br />
require 'spec/story'<br />
&nbsp;&nbsp;<br />
steps_for(:login) do<br />
&nbsp;&nbsp;Given "我的账户为$email" do |email|<br />
&nbsp;&nbsp;&nbsp;&nbsp;@user = find_or_create_user_by_email({:email =&gt; email,<br />
&nbsp;&nbsp;&nbsp;&nbsp;:password =&gt; 'foofoo',<br />
&nbsp;&nbsp;&nbsp;&nbsp;:password_confirmation =&gt; 'foofoo'})<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;When "我用邮箱为$email和密码是$password进行登录" do |email, password|<br />
&nbsp;&nbsp;&nbsp;&nbsp;post '/login', :user =&gt; {:email =&gt; email, :password =&gt; password}<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;Then("我能够登录") do<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;Then("我会看到账户页面") do<br />
&nbsp;&nbsp;end<br />
end<br />
&nbsp;&nbsp;<br />
with_steps_for(:login) do<br />
&nbsp;&nbsp;run "login"<br />
end</code></p>
<p>参考：<br />
<a href="http://rspec.info/">http://rspec.info/</a><br />
<a href="http://blog.davidchelimsky.net/articles/2007/10/22/plain-text-stories-on-rails">http://blog.davidchelimsky.net/articles/2007/10/22/plain-text-stories-on-rails</a><br />
<a href="http://dannorth.net/whats-in-a-story">http://dannorth.net/whats-in-a-story</a><br />
<a href="http://www.letrails.cn/archives/rspec-story-tutorials">http://www.letrails.cn/archives/rspec-story-tutorials</a>（上一链接文章的中译版）</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/05/01/rspec%e7%9a%84stroy%e6%a1%86%e6%9e%b6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我要改变世界</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/30/%e6%88%91%e8%a6%81%e6%94%b9%e5%8f%98%e4%b8%96%e7%95%8c/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/30/%e6%88%91%e8%a6%81%e6%94%b9%e5%8f%98%e4%b8%96%e7%95%8c/#comments</comments>
		<pubDate>Wed, 30 Apr 2008 15:14:47 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/30/%e6%88%91%e8%a6%81%e6%94%b9%e5%8f%98%e4%b8%96%e7%95%8c/</guid>
		<description><![CDATA[如此的现实如此的不堪，如此的不合情理。
我要获得改变这个世界的能力。然后去改变世界，改变所谓的现实
我憎恨丑恶的东西，还有憎恨师兄这个词。。。
]]></description>
			<content:encoded><![CDATA[<p>如此的现实如此的不堪，如此的不合情理。</p>
<p>我要获得改变这个世界的能力。然后去改变世界，改变所谓的现实</p>
<p>我憎恨丑恶的东西，还有憎恨师兄这个词。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/30/%e6%88%91%e8%a6%81%e6%94%b9%e5%8f%98%e4%b8%96%e7%95%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>txt2html脚本</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/28/txt2html%e8%84%9a%e6%9c%ac/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/28/txt2html%e8%84%9a%e6%9c%ac/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 15:52:43 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/28/txt2html%e8%84%9a%e6%9c%ac/</guid>
		<description><![CDATA[一个把Markdown或（和）Textile的文本转化为Html的脚本，使用RedCloth，简单轻便。。。

#!/usr/bin/ruby -w
# txt2html.rb
# Usege:
# run commands like: ruby txt2html.rb the_file_you_want_to_do_covert
require "rubygems"
require "redcloth"
filename = ARGV.first
contents = ''
open("#{filename}") { &#124;f&#124; contents = f.read }
open("#{filename[0, filename.length-4]}.html",'w') { &#124;f&#124; f&#60;&#60;RedCloth.new(contents).to_html }

]]></description>
			<content:encoded><![CDATA[<p>一个把Markdown或（和）Textile的文本转化为Html的脚本，使用RedCloth，简单轻便。。。<br />
<span id="more-74"></span><br />
<code>#!/usr/bin/ruby -w<br />
# txt2html.rb<br />
# Usege:<br />
# run commands like: ruby txt2html.rb the_file_you_want_to_do_covert<br />
require "rubygems"<br />
require "redcloth"<br />
filename = ARGV.first<br />
contents = ''<br />
open("#{filename}") { |f| contents = f.read }<br />
open("#{filename[0, filename.length-4]}.html",'w') { |f| f&lt;&lt;RedCloth.new(contents).to_html }<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/28/txt2html%e8%84%9a%e6%9c%ac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>见识了家庭小作坊式生产</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/27/%e8%a7%81%e8%af%86%e4%ba%86%e5%ae%b6%e5%ba%ad%e5%b0%8f%e4%bd%9c%e5%9d%8a%e5%bc%8f%e7%94%9f%e4%ba%a7/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/27/%e8%a7%81%e8%af%86%e4%ba%86%e5%ae%b6%e5%ba%ad%e5%b0%8f%e4%bd%9c%e5%9d%8a%e5%bc%8f%e7%94%9f%e4%ba%a7/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 12:54:15 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/27/%e8%a7%81%e8%af%86%e4%ba%86%e5%ae%b6%e5%ba%ad%e5%b0%8f%e4%bd%9c%e5%9d%8a%e5%bc%8f%e7%94%9f%e4%ba%a7/</guid>
		<description><![CDATA[今天去惠东考察一家鞋厂，见识了什么是家庭小作坊式生产。

一个不大的厂房，两层，几十个工人。家庭式管理，中央集权式，客户下订，来料加工。样板管理，全部由师傅（款式设计师），样板用完很快就丢弃，不去分析。供应链无序，做生意靠信用，各方面的分工不细致，整个厂的权利和事务全部集中于老板一人，剩下的管理者基本都是老板的亲戚。老板基本认为电子商务没前途，强调鞋业生产的特殊性（他的说法没错）。
期间，厂长说“界面要做出一个架构出来”，接着说“就是要能够看到一些框框，然后可以输入东西。”我晕忽忽，“架构”他们是这样理解。
由于国人的生产劳动力依然廉价，生产自动化难以普及，由于规模较小导致管理集权，生产由客户来单驱动，缺乏市场分析，分工粒度较小。不知道多久之后中国的制造业才能实现信息化自动化。
]]></description>
			<content:encoded><![CDATA[<p>今天去惠东考察一家鞋厂，见识了什么是家庭小作坊式生产。<br />
<span id="more-73"></span><br />
一个不大的厂房，两层，几十个工人。家庭式管理，中央集权式，客户下订，来料加工。样板管理，全部由师傅（款式设计师），样板用完很快就丢弃，不去分析。供应链无序，做生意靠信用，各方面的分工不细致，整个厂的权利和事务全部集中于老板一人，剩下的管理者基本都是老板的亲戚。老板基本认为电子商务没前途，强调鞋业生产的特殊性（他的说法没错）。</p>
<p>期间，厂长说“界面要做出一个架构出来”，接着说“就是要能够看到一些框框，然后可以输入东西。”我晕忽忽，“架构”他们是这样理解。</p>
<p>由于国人的生产劳动力依然廉价，生产自动化难以普及，由于规模较小导致管理集权，生产由客户来单驱动，缺乏市场分析，分工粒度较小。不知道多久之后中国的制造业才能实现信息化自动化。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/27/%e8%a7%81%e8%af%86%e4%ba%86%e5%ae%b6%e5%ba%ad%e5%b0%8f%e4%bd%9c%e5%9d%8a%e5%bc%8f%e7%94%9f%e4%ba%a7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我翻译的文章被rubyonrailscn.org的wiki收录啦</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/27/%e6%88%91%e7%bf%bb%e8%af%91%e7%9a%84%e6%96%87%e7%ab%a0%e8%a2%abrubyonrailscnorg%e7%9a%84wiki%e6%94%b6%e5%bd%95%e5%95%a6/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/27/%e6%88%91%e7%bf%bb%e8%af%91%e7%9a%84%e6%96%87%e7%ab%a0%e8%a2%abrubyonrailscnorg%e7%9a%84wiki%e6%94%b6%e5%bd%95%e5%95%a6/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 12:07:03 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/27/%e6%88%91%e7%bf%bb%e8%af%91%e7%9a%84%e6%96%87%e7%ab%a0%e8%a2%abrubyonrailscnorg%e7%9a%84wiki%e6%94%b6%e5%bd%95%e5%95%a6/</guid>
		<description><![CDATA[昨天	rubyonrailscn.org 发给 我 的消息
标题:	Re: Re: 征询你的同意，我们希望把你的一些文章收入到 Ruby on Rails 中文 wiki 内容库中
正文:
chenk85, 你好！
谢谢你的同意！
你的文章《[翻译]来自Rails Envy的Rails Cache教程 part1》已经被收入和整理在 Rails 知识库中的如下地址：
http://wiki.rubyonrailscn.org/rails/show/RailsEnvyRailsCachePart1
请看一下，如果有问题的话请和我联系。
谢谢你对Rails中文站的支持，希望不久能看到更多你的作品。
Ruby on Rails 中文网站
Web: http://www.rubyonrailscn.org/
Email contact@rubyonrailscn.org 
呵呵。。。
]]></description>
			<content:encoded><![CDATA[<blockquote><p>昨天	rubyonrailscn.org 发给 我 的消息<br />
标题:	Re: Re: 征询你的同意，我们希望把你的一些文章收入到 Ruby on Rails 中文 wiki 内容库中<br />
正文:<br />
chenk85, 你好！</p>
<p>谢谢你的同意！</p>
<p>你的文章《[翻译]来自Rails Envy的Rails Cache教程 part1》已经被收入和整理在 Rails 知识库中的如下地址：</p>
<p>http://wiki.rubyonrailscn.org/rails/show/RailsEnvyRailsCachePart1</p>
<p>请看一下，如果有问题的话请和我联系。</p>
<p>谢谢你对Rails中文站的支持，希望不久能看到更多你的作品。</p>
<p>Ruby on Rails 中文网站<br />
Web: http://www.rubyonrailscn.org/<br />
Email contact@rubyonrailscn.org </p></blockquote>
<p>呵呵。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/27/%e6%88%91%e7%bf%bb%e8%af%91%e7%9a%84%e6%96%87%e7%ab%a0%e8%a2%abrubyonrailscnorg%e7%9a%84wiki%e6%94%b6%e5%bd%95%e5%95%a6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>敏捷的证据在哪里？</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/24/%e6%95%8f%e6%8d%b7%e7%9a%84%e8%af%81%e6%8d%ae%e5%9c%a8%e5%93%aa%e9%87%8c%ef%bc%9f/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/24/%e6%95%8f%e6%8d%b7%e7%9a%84%e8%af%81%e6%8d%ae%e5%9c%a8%e5%93%aa%e9%87%8c%ef%bc%9f/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 12:26:07 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[Agile]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/24/%e6%95%8f%e6%8d%b7%e7%9a%84%e8%af%81%e6%8d%ae%e5%9c%a8%e5%93%aa%e9%87%8c%ef%bc%9f/</guid>
		<description><![CDATA[敏捷能提高软件生产力的证据就在《Agile &#38; Iterative Development &#8211; A Manager&#8217;s Guide》这本书的六章中。书中举出了许多具体的数据来证实敏捷/迭代和瀑布相比的成功率，缺陷率，代码生产率等等。
]]></description>
			<content:encoded><![CDATA[<p>敏捷能提高软件生产力的证据就在《Agile &amp; Iterative Development &#8211; A Manager&#8217;s Guide》这本书的六章中。书中举出了许多具体的数据来证实敏捷/迭代和瀑布相比的成功率，缺陷率，代码生产率等等。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/24/%e6%95%8f%e6%8d%b7%e7%9a%84%e8%af%81%e6%8d%ae%e5%9c%a8%e5%93%aa%e9%87%8c%ef%bc%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZenTest1.0代码分析</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/20/zentest10%e4%bb%a3%e7%a0%81%e5%88%86%e6%9e%90/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/20/zentest10%e4%bb%a3%e7%a0%81%e5%88%86%e6%9e%90/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 13:46:55 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/20/zentest10%e4%bb%a3%e7%a0%81%e5%88%86%e6%9e%90/</guid>
		<description><![CDATA[ZenTest是Ruby的一个确保测试覆盖率和促进TDD实行（Ensures test coverage and accelerates TDD）的代码生成框架，并带有其它的实用工具（autotest等等）。官方主页：http://www.zenspider.com/ZSS/Products/ZenTest/
这次我选了ZenTest的1.0版来研究，代码文件大小只有3.7K，144行。

下面是代码：
#!/usr/local/bin/ruby -w -I.
&#160;
VERSION = '1.0.0'
&#160;
puts "# Created with ZenTest v. #{VERSION}"
&#160;
$AUTOTESTER = true
&#160;
# 重写at_exit方法，让该方法不做任何事情
module Kernel
&#160; alias :old_at_exit :at_exit
&#160;  def at_exit()
&#160;&#160;    # nothing to do...
&#160;  end
end
&#160;
require 'test/unit'
require 'test/unit/ui/console/testrunner'
&#160;
# 产生文件的副本
files = ARGV.clone
&#160;
# 保存测试类的hash（ klass -&#62; klassmethods）
test_klasses = {}
# 保存待测试类的hash（ klass -&#62; klassmethods）
klasses = {}
# 保存待测试类的方法的hash（ klass -&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>ZenTest是Ruby的一个确保测试覆盖率和促进TDD实行（Ensures test coverage and accelerates TDD）的代码生成框架，并带有其它的实用工具（autotest等等）。官方主页：http://www.zenspider.com/ZSS/Products/ZenTest/</p>
<p>这次我选了ZenTest的1.0版来研究，代码文件大小只有3.7K，144行。<br />
<span id="more-71"></span><br />
下面是代码：<br />
<code>#!/usr/local/bin/ruby -w -I.<br />
&nbsp;<br />
VERSION = '1.0.0'<br />
&nbsp;<br />
puts "# Created with ZenTest v. #{VERSION}"<br />
&nbsp;<br />
$AUTOTESTER = true<br />
&nbsp;<br />
# 重写at_exit方法，让该方法不做任何事情<br />
module Kernel<br />
&nbsp; alias :old_at_exit :at_exit<br />
&nbsp;  def at_exit()<br />
&nbsp;&nbsp;    # nothing to do...<br />
&nbsp;  end<br />
end<br />
&nbsp;<br />
require 'test/unit'<br />
require 'test/unit/ui/console/testrunner'<br />
&nbsp;<br />
# 产生文件的副本<br />
files = ARGV.clone<br />
&nbsp;<br />
# 保存测试类的hash（ klass -&gt; klassmethods）<br />
test_klasses = {}<br />
# 保存待测试类的hash（ klass -&gt; klassmethods）<br />
klasses = {}<br />
# 保存待测试类的方法的hash（ klass -&gt; klassmethods）<br />
all_methods = {} # fallback<br />
&nbsp;<br />
# 迭代处理参数指定的每个文件<br />
ARGV.each do |file|<br />
&nbsp;<br />
&nbsp;  # 导入文件，失败则抛出异常，并输出错误信息<br />
&nbsp;  begin<br />
&nbsp;&nbsp;    require "#{file}"<br />
&nbsp;  rescue LoadError =&gt; err<br />
&nbsp;&nbsp;    puts "Couldn't load #{file}: #{err}"<br />
&nbsp;&nbsp;    next<br />
&nbsp;  end<br />
&nbsp;<br />
&nbsp;  # 迭代处理文件的每一行<br />
&nbsp;  IO.foreach(file) do |line|<br />
 &nbsp;   # 如果该行中包含类定义（class Xxx）则处理<br />
&nbsp;    if line =~ /^\s*class\s+(\S+)/ then<br />
 &nbsp;&nbsp;     # 保存类名<br />
 &nbsp;&nbsp;     klassname = $1<br />
 &nbsp;&nbsp;     # 将类名转换为Symbol后再得到该类的类型值<br />
 &nbsp;&nbsp;     klass = Module.const_get(klassname.intern)<br />
 &nbsp;&nbsp;     # 如果该类为单元测试类<br />
&nbsp;&nbsp;      target = klassname =~ /^Test/ ? test_klasses : klasses<br />
&nbsp;<br />
&nbsp;&nbsp;      # record public instance methods JUST in this class<br />
&nbsp;&nbsp;      # 保存类的公用实例方法到一个methond -&gt; boolean的Hash中<br />
&nbsp;&nbsp;      # 并将该Hash保存到以该类为键值的target hash中<br />
&nbsp;&nbsp;      public_methods = klass.public_instance_methods<br />
 &nbsp;&nbsp;     klassmethods = {}<br />
&nbsp;&nbsp;      public_methods.each do |meth|<br />
 &nbsp;&nbsp;       klassmethods[meth] = true<br />
 &nbsp;     end<br />
&nbsp;      target[klassname] = klassmethods<br />
&nbsp;<br />
&nbsp;      # record ALL instance methods including superclasses (minus Object)<br />
&nbsp;      # 将该类中由Object类继承的实例方法除去后保存<br />
&nbsp;      the_methods = klass.instance_methods(true) - Object.instance_methods(true)<br />
&nbsp;      # 生成同上个代码块类似的hash<br />
&nbsp;      klassmethods = {}<br />
&nbsp;      the_methods.each do |meth|<br />
&nbsp;&nbsp;        klassmethods[meth] = true<br />
&nbsp;      end<br />
&nbsp;      all_methods[klassname] = klassmethods<br />
&nbsp;    end<br />
&nbsp;  end<br />
end<br />
&nbsp;<br />
# 上面的迭代代码块运行完成后将记录下文件中所有类和其公共的实例方法<br />
&nbsp;<br />
print "# "<br />
p all_methods<br />
&nbsp;<br />
missing_methods = {} # key = klassname, val = array of methods<br />
# 在待测试类上进行迭代（以待测试类的名字）<br />
klasses.each_key do |klassname|<br />
&nbsp;  # 生成测试类类名<br />
&nbsp;  testklassname = "Test#{klassname}"<br />
&nbsp;<br />
&nbsp;  if test_klasses[testklassname] then<br />
&nbsp;&nbsp;    methods = klasses[klassname]<br />
&nbsp;&nbsp;    testmethods = test_klasses[testklassname]<br />
&nbsp;<br />
&nbsp;&nbsp;    # check that each method has a test method<br />
&nbsp;&nbsp;    # 检查每个方法是否有一个测试方法<br />
 &nbsp;&nbsp;   klasses[klassname].each_key do | methodname |<br />
 &nbsp;&nbsp;     testmethodname = "test_#{methodname}".gsub(/\[\]=/, "index_equals").gsub(/\[\]/, "index_accessor")<br />
 &nbsp;&nbsp;     unless testmethods[testmethodname] then<br />
 &nbsp;&nbsp;       puts "# ERROR method #{testklassname}\##{testmethodname} does not exist (1)" if $VERBOSE<br />
 &nbsp;&nbsp;       missing_methods[testklassname] ||= []<br />
&nbsp;&nbsp;        missing_methods[testklassname].push(testmethodname)<br />
&nbsp;&nbsp;      end<br />
&nbsp;    end<br />
&nbsp;    # check that each test method has a method<br />
&nbsp;    testmethods.each_key do | testmethodname |<br />
&nbsp;      if testmethodname =~ /^test_(.*)/ then<br />
 &nbsp;&nbsp;       methodname = $1.gsub(/index_equals/, "[]=").gsub(/index_accessor/, "[]")<br />
&nbsp;&nbsp;        # try the current name<br />
&nbsp;&nbsp;        orig_name = methodname.dup<br />
&nbsp;&nbsp;        found = false<br />
 &nbsp;&nbsp;       until methodname == "" or methods[methodname] or all_methods[klassname][methodname] do<br />
&nbsp;&nbsp;          # try the name minus an option (ie mut_opt1 -&gt; mut)<br />
&nbsp;&nbsp;          if methodname.sub!(/_[^_]+$/, '') then<br />
 &nbsp;&nbsp;           if methods[methodname] or all_methods[klassname][methodname] then<br />
&nbsp;&nbsp;              found = true<br />
&nbsp;&nbsp;            end<br />
&nbsp;&nbsp;          else<br />
&nbsp;&nbsp;            break # no more substitutions will take place<br />
&nbsp;&nbsp;          end<br />
 &nbsp;&nbsp;       end<br />
&nbsp;<br />
 &nbsp;&nbsp;       unless found or methods[methodname] or methodname == "initialize" then<br />
&nbsp;&nbsp;          puts "# ERROR method #{klassname}\##{orig_name} does not exist (2)" if $VERBOSE<br />
&nbsp;&nbsp;          missing_methods[klassname] ||= []<br />
&nbsp;&nbsp;          missing_methods[klassname].push(orig_name)<br />
 &nbsp;&nbsp;       end<br />
&nbsp;&nbsp;      else<br />
   &nbsp;&nbsp;     unless testmethodname =~ /^util_/ then<br />
  &nbsp;&nbsp;        puts "# WARNING Skipping #{testklassname}\##{testmethodname}"<br />
  &nbsp;&nbsp;      end<br />
  &nbsp;&nbsp;    end<br />
&nbsp;&nbsp;    end<br />
&nbsp;  else<br />
 &nbsp;&nbsp;   puts "# ERROR test class #{testklassname} does not exist" if $VERBOSE<br />
&nbsp;<br />
 &nbsp;&nbsp;   missing_methods[testklassname] ||= []<br />
&nbsp;&nbsp;    klasses[klassname].keys.each do |meth|<br />
 &nbsp;&nbsp;     missing_methods[testklassname].push("test_#{meth}")<br />
 &nbsp;   end<br />
 &nbsp; end<br />
end<br />
# 真正地创建测试类，为没有测试的类添加方法。<br />
missing_methods.keys.sort.each do |klass|<br />
 &nbsp; # 判断是否为测试类<br />
&nbsp;  testklass = klass =~ /^Test/<br />
&nbsp;<br />
&nbsp;  puts "class #{klass}" + (testklass ? " &lt; Test::Unit::TestCase" : '')<br />
&nbsp;<br />
 &nbsp; methods = missing_methods[klass] | []<br />
 &nbsp; m = []<br />
 &nbsp; methods.sort.each do |method|<br />
&nbsp;    # 为测试类生成代码<br />
&nbsp;    if testklass then<br />
 &nbsp;&nbsp;     s = "  def #{method}\n    assert(false, 'Need to write #{method} tests')\n  end"<br />
&nbsp;    else<br />
 &nbsp;&nbsp;     s = "  def #{method}\n    # TO" + "DO: write some code\n  end"<br />
&nbsp;&nbsp;    end<br />
&nbsp;&nbsp;    m.push(s)<br />
&nbsp;  end<br />
&nbsp;<br />
&nbsp;&nbsp;  puts m.join("\n\n")<br />
&nbsp;<br />
&nbsp;&nbsp;  puts "end"<br />
&nbsp;&nbsp;  puts ""<br />
end</code></p>
<p>整个程序的主要分为三个部分，第一个是导入文件并收集文件中的类的信息，第二部分是收集前一部分收集到的类的方法的信息进行处理，最后是生成测试类的代码。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/20/zentest10%e4%bb%a3%e7%a0%81%e5%88%86%e6%9e%90/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HP6520s与ArchLinux</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/14/hp6520s%e4%b8%8earchlinux/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/14/hp6520s%e4%b8%8earchlinux/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 01:30:43 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[NoteBook]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/14/hp6520s%e4%b8%8earchlinux/</guid>
		<description><![CDATA[安装Arch的方法很简单，但是记得在分区时要把swap设置到大于等于内存容量，才能休眠。一开始没有设好swap，结果怎么也休眠不了。
由于本本的特殊性要安装下列软件包：
apci,apcid &#8211; 高级电源支持
dus hal udev &#8211; 自动挂载
pmtools &#8211; 休眠
powertop &#8211; 本本节能工具
hotkey-setup laptop-mode-tools &#8211; 笔记本支持工具
cpudyn cpufreqd cpufrequtils CPU支持
iwlwifi-3945-ucode &#8211; 无线网卡驱动
参考
http://wiki.archlinux.org/index.php/Laptop
http://wiki.archlinux.org/index.php/Pm-utils
http://wiki.archlinux.org/index.php/Cpufrequtils
http://wiki.archlinux.org/index.php/Networkmanager
安装并设置了这些后就能很好的支持到笔记本的各种特性，如休眠，Fn键，自动降频，电池电量显示，无线等。
]]></description>
			<content:encoded><![CDATA[<p>安装Arch的方法很简单，但是记得在分区时要把swap设置到大于等于内存容量，才能休眠。一开始没有设好swap，结果怎么也休眠不了。</p>
<p>由于本本的特殊性要安装下列软件包：<br />
apci,apcid &#8211; 高级电源支持<br />
dus hal udev &#8211; 自动挂载<br />
pmtools &#8211; 休眠<br />
powertop &#8211; 本本节能工具<br />
hotkey-setup laptop-mode-tools &#8211; 笔记本支持工具<br />
cpudyn cpufreqd cpufrequtils CPU支持<br />
iwlwifi-3945-ucode &#8211; 无线网卡驱动<br />
参考<br />
http://wiki.archlinux.org/index.php/Laptop<br />
http://wiki.archlinux.org/index.php/Pm-utils<br />
http://wiki.archlinux.org/index.php/Cpufrequtils<br />
http://wiki.archlinux.org/index.php/Networkmanager</p>
<p>安装并设置了这些后就能很好的支持到笔记本的各种特性，如休眠，Fn键，自动降频，电池电量显示，无线等。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/14/hp6520s%e4%b8%8earchlinux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>我的第一台本本HP6520s</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/04/14/%e6%88%91%e7%9a%84%e7%ac%ac%e4%b8%80%e5%8f%b0%e6%9c%ac%e6%9c%achp6520s/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/04/14/%e6%88%91%e7%9a%84%e7%ac%ac%e4%b8%80%e5%8f%b0%e6%9c%ac%e6%9c%achp6520s/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 00:29:34 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[NoteBook]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/04/14/%e6%88%91%e7%9a%84%e7%ac%ac%e4%b8%80%e5%8f%b0%e6%9c%ac%e6%9c%achp6520s/</guid>
		<description><![CDATA[
买回来了本本HP6520s（KS260PA）。6850RMB（一本，一电，一鼠，一包，一清洁）+135RMB（1条KS的内存）。



买本本的经历比较简单，一开始去本地HP代理问过一下价格，然后就叫他拿货，之后就去到验机（看序列号是否一致），测试（用Ubuntu的Live CD），带回来。
在中关村的资料：http://detail.zol.com.cn/notebook/index139838.shtml
配置上的确是不错的，迅驰4.5的T8100，加了1G的内存，升到2G，加上是800的前端，速度果然是飞快。发热也不厉害，电池能顶3个小时左右。唯一不满的地方就是屏幕，显示效果有点差，好像看网上的评价，基本都是说显示效果差。
[chenkai@localhost ~]$ cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 23
model name	: Intel(R) Core(TM)2 Duo CPU     T8100  @ 2.10GHz
stepping	: 6
cpu MHz		: 800.000
cache size	: 3072 KB
physical id	: 0
siblings	: 2
core id		: 0
cpu cores	: 2
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 10
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://lh3.ggpht.com/chenk85/SAK47kDaDbI/AAAAAAAAABQ/W32IL9wxtZI/20080414261.jpg?imgmax=576" alt="2601" /></p>
<p>买回来了本本HP6520s（KS260PA）。6850RMB（一本，一电，一鼠，一包，一清洁）+135RMB（1条KS的内存）。</p>
<p><span id="more-70"></span></p>
<p><img src="http://lh4.ggpht.com/chenk85/SAK470DaDcI/AAAAAAAAABY/QFcMY8AxAKc/20080414262.jpg?imgmax=576" alt="2602" /></p>
<p><img src="http://lh4.ggpht.com/chenk85/SAK470DaDdI/AAAAAAAAABg/2jmA1rOWH2c/20080414263.jpg?imgmax=576" alt="2603" /></p>
<p>买本本的经历比较简单，一开始去本地HP代理问过一下价格，然后就叫他拿货，之后就去到验机（看序列号是否一致），测试（用Ubuntu的Live CD），带回来。</p>
<p>在中关村的资料：http://detail.zol.com.cn/notebook/index139838.shtml</p>
<p>配置上的确是不错的，迅驰4.5的T8100，加了1G的内存，升到2G，加上是800的前端，速度果然是飞快。发热也不厉害，电池能顶3个小时左右。唯一不满的地方就是屏幕，显示效果有点差，好像看网上的评价，基本都是说显示效果差。</p>
<p><code>[chenkai@localhost ~]$ cat /proc/cpuinfo<br />
processor	: 0<br />
vendor_id	: GenuineIntel<br />
cpu family	: 6<br />
model		: 23<br />
model name	: Intel(R) Core(TM)2 Duo CPU     T8100  @ 2.10GHz<br />
stepping	: 6<br />
cpu MHz		: 800.000<br />
cache size	: 3072 KB<br />
physical id	: 0<br />
siblings	: 2<br />
core id		: 0<br />
cpu cores	: 2<br />
fdiv_bug	: no<br />
hlt_bug		: no<br />
f00f_bug	: no<br />
coma_bug	: no<br />
fpu		: yes<br />
fpu_exception	: yes<br />
cpuid level	: 10<br />
wp		: yes<br />
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr sse4_1 lahf_lm ida<br />
bogomips	: 4194.59<br />
clflush size	: 64<br />
processor	: 1<br />
vendor_id	: GenuineIntel<br />
cpu family	: 6<br />
model		: 23<br />
model name	: Intel(R) Core(TM)2 Duo CPU     T8100  @ 2.10GHz<br />
stepping	: 6<br />
cpu MHz		: 800.000<br />
cache size	: 3072 KB<br />
physical id	: 0<br />
siblings	: 2<br />
core id		: 1<br />
cpu cores	: 2<br />
fdiv_bug	: no<br />
hlt_bug		: no<br />
f00f_bug	: no<br />
coma_bug	: no<br />
fpu		: yes<br />
fpu_exception	: yes<br />
cpuid level	: 10<br />
wp		: yes<br />
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr sse4_1 lahf_lm ida<br />
bogomips	: 4191.10<br />
clflush size	: 64<br />
</code></p>
<p>CPU是最强的部分:)</p>
<p>买回来后就装上了Arch Linux，详见我另一日志。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/04/14/%e6%88%91%e7%9a%84%e7%ac%ac%e4%b8%80%e5%8f%b0%e6%9c%ac%e6%9c%achp6520s/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>了解Server PUSH</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/03/14/server-push/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/03/14/server-push/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 15:14:46 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/03/14/server-push/</guid>
		<description><![CDATA[这几天在作Web聊天室的实现，看到了Server Push的概念，找到两篇国人的文章。
http://lightyror.thegiive.net/2007/06/comet-push-server.html
http://www.javaeye.com/topic/19089
]]></description>
			<content:encoded><![CDATA[<p>这几天在作Web聊天室的实现，看到了Server Push的概念，找到两篇国人的文章。</p>
<blockquote><p><a href="http://lightyror.thegiive.net/2007/06/comet-push-server.html">http://lightyror.thegiive.net/2007/06/comet-push-server.html</a><br />
<a href="http://www.javaeye.com/topic/19089">http://www.javaeye.com/topic/19089</a></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/03/14/server-push/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>autotest的notify in Gnome</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/03/13/autotest-notify-in-gnome/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/03/13/autotest-notify-in-gnome/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 05:46:23 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/03/13/autotest%e7%9a%84notify%ef%bc%88gnome%e4%b8%8b%ef%bc%89/</guid>
		<description><![CDATA[autotest是个方便的测试工具，ZenTest的组件之一，对Rspec支持很好。
在Peedcode的教学视频中很多时候看到作者用autotest时，测试结果会以桌面系统Notify的形式通知用户，每次看到都觉得好羡慕。其实在Gnome环境下的同学不用羡慕，因为在Gnome下也可以，把你Home目录下的.autotest文件（附件有），加入以下代码，并把附件中的图片文件放到Home下（把dot改为.）。
require 'rnotify'
require 'gtk2'
&#160;
module Autotest::RNotify
&#160;  class Notification
&#160;&#160;    attr_accessor :verbose, :image_root, :tray_icon, :notification,
&#160;&#160;                  :image_pass, :image_pending, :image_fail
    &#160;
&#160;&#160;    def initialize(timeout = 5000,
&#160;&#160;          [...]]]></description>
			<content:encoded><![CDATA[<p>autotest是个方便的测试工具，ZenTest的组件之一，对Rspec支持很好。</p>
<p>在Peedcode的教学视频中很多时候看到作者用autotest时，测试结果会以桌面系统Notify的形式通知用户，每次看到都觉得好羡慕。其实在Gnome环境下的同学不用羡慕，因为在Gnome下也可以，把你<strong>Home目录下的.autotest</strong>文件（附件有），加入以下代码，并把附件中的图片文件放到Home下（把<strong>dot改为.</strong>）。<span id="more-65"></span></p>
<p><code>require 'rnotify'<br />
require 'gtk2'<br />
&nbsp;<br />
module Autotest::RNotify<br />
&nbsp;  class Notification<br />
&nbsp;&nbsp;    attr_accessor :verbose, :image_root, :tray_icon, :notification,<br />
&nbsp;&nbsp;                  :image_pass, :image_pending, :image_fail<br />
    &nbsp;<br />
&nbsp;&nbsp;    def initialize(timeout = 5000,<br />
&nbsp;&nbsp;                   image_root = "#{ENV['HOME']}/.autotest_images" ,<br />
&nbsp;&nbsp;                   verbose = false)<br />
 &nbsp;&nbsp;&nbsp;     self.verbose = verbose<br />
  &nbsp;&nbsp;&nbsp;    self.image_root = image_root<br />
      &nbsp;<br />
  &nbsp;&nbsp;&nbsp;   puts 'Autotest Hook: loading Notify' if verbose<br />
  &nbsp;&nbsp;&nbsp;    Notify.init('Autotest') || raise('Failed to initialize Notify')<br />
&nbsp;<br />
 &nbsp;&nbsp;&nbsp;     puts 'Autotest Hook: initializing tray icon' if verbose<br />
   &nbsp;&nbsp;&nbsp;   self.tray_icon = Gtk::StatusIcon.new<br />
 &nbsp;&nbsp;&nbsp;     tray_icon.icon_name = 'face-monkey'<br />
 &nbsp;&nbsp;&nbsp;     tray_icon.tooltip = 'RSpec Autotest'<br />
&nbsp;<br />
   &nbsp;&nbsp;&nbsp;   puts 'Autotest Hook: Creating Notifier' if verbose<br />
  &nbsp;&nbsp;&nbsp;    self.notification = Notify::Notification.new('X', nil, nil, tray_icon)<br />
  &nbsp;&nbsp;&nbsp;    notification.timeout = timeout<br />
      &nbsp;<br />
   &nbsp;&nbsp;&nbsp;   Thread.new { Gtk.main }<br />
 &nbsp;&nbsp;&nbsp;     sleep 1<br />
  &nbsp;&nbsp;&nbsp;    tray_icon.embedded? || raise('Failed to set up tray icon')<br />
 &nbsp;&nbsp;   end<br />
    &nbsp;<br />
  &nbsp;&nbsp;&nbsp;  def notify(icon, tray, title, message)<br />
   &nbsp;&nbsp;&nbsp;   notification.update(title, message, nil)<br />
      notification.pixbuf_icon = icon<br />
      tray_icon.tooltip = "Last Result: #{message}"<br />
      tray_icon.icon_name = tray<br />
      notification.show<br />
    end<br />
    &nbsp;<br />
    def passed(title, message)<br />
      self.image_pass ||= Gdk::Pixbuf.new("#{image_root}/pass.png", 48,48)<br />
      notify(image_pass, 'face-smile', title, message)<br />
    end<br />
    &nbsp;<br />
    def pending(title, message)<br />
      self.image_pending ||= Gdk::Pixbuf.new("#{image_root}/pending.png",48,48)<br />
      notify(image_pending, 'face-plain', title, message)<br />
    end<br />
    &nbsp;<br />
    def failed(title, message)<br />
      self.image_fail ||= Gdk::Pixbuf.new("#{image_root}/fail.png", 48,48)<br />
      notify(image_fail, 'face-sad', title, message)<br />
    end<br />
    &nbsp;<br />
    def quit<br />
      puts 'Autotest Hook: Shutting Down...' if verbose<br />
      #Notify.uninit<br />
      Gtk.main_quit<br />
    end<br />
  end<br />
&nbsp;<br />
  Autotest.add_hook :initialize do |at|<br />
    @notify = Notification.new<br />
  end<br />
&nbsp;<br />
  Autotest.add_hook :ran_command do |at|<br />
    results = at.results.last<br />
&nbsp;<br />
    puts "the results is #{results}"<br />
&nbsp;<br />
    unless results.nil?<br />
      output = results[/(\d+)\s+example?,\s*(\d+)\s+failures?(,\s*(\d+)\s+peding)?/]<br />
&nbsp;<br />
      if $~[2].to_i &gt; 0<br />
        @notify.failed("Tests Failed", output)<br />
      elsif $~[4].to_i &gt; 0<br />
        @notify.pending("Tests Pending", output)<br />
      else<br />
        unless at.tainted<br />
          @notify.passed("All Tests Passed", output)<br />
        else<br />
          @notify.passed("Tests Passed", output)<br />
        end<br />
      end<br />
    end<br />
  end<br />
&nbsp;<br />
&nbsp;  Autotest.add_hook :quit do |at|<br />
&nbsp;&nbsp;    @notify.quit<br />
 &nbsp; end<br />
end</code></p>
<p>ohoh～～我们来看看效果怎样，在任意一个加入rspec on rails插件的Project下（当然是写了spec的）执行autotest：<br />
<a href='http://redworld.blog.ubuntu.org.cn/2008/03/13/autotest-notify-in-gnome/notifypng/' rel='attachment wp-att-67' title='notify.png'><img src='http://redworld.blog.ubuntu.org.cn/files/2008/03/notify.png' alt='notify.png' /></a></p>
<p>是不是很有趣呢？当然这个依赖于库ruby-gnome2，ruby-libnotify，都是用各自Linux发行班的包管理软件可以轻松得到的，比如我的arch就是，yaourt ruby-gnome2 ruby-libnotify。这个其实也可以用在unit test下，不过需要修改Autotest.add_hook :ran_command中的正则。</p>
<p>Ruby一个可爱的地方就是配置文件也是代码，代码还是代码。autotest的扩展性真好，这也是得益于Ruby的哲学，要修改一个类的行为就打开它，定义它，很优雅。Code is the best firend of Programmer 。</p>
<p>参考资料：<br />
http://www.ikhono.net/2007/12/16/gnome-autotest-notifications</p>
<p><a href='http://redworld.blog.ubuntu.org.cn/2008/03/13/autotest-notify-in-gnome/dot_autotest_imageszip/' rel='attachment wp-att-66' title='dot_autotest_images.zip'>dot_autotest_images.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/03/13/autotest-notify-in-gnome/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>After Eager Loading</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/03/13/after-eager-loading/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/03/13/after-eager-loading/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 05:05:23 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/03/13/after-eager-loading/</guid>
		<description><![CDATA[Eager Loading是ActiveRecord的一个数据查询的优化措施，在查询model的时候连同它的关联对象都全查询出来（通过一条包含LEFT OUTER JOIN的SQL语句）。但是在你使用了Eager Loading后，如果还是用一些会触发数据库本身的统计函数的查询方法（如count，average等）的话，那前面的Eager Loading就白费了。下面给出例子：
两个Model，Project和Task，关系是Project has_many Task。
在ProjectController的show中：
@project&#160;=&#160;Project.find(params[:id],&#160;:include&#160;=&#62;&#160;[:articles,&#160;:tasks])
这是project/show页面：
&#60;h1&#62;&#60;%=h&#160;@project.title&#160;%&#62;&#60;/h1&#62;&#160;&#60;h2&#62;&#60;%=h&#160;@project.description&#160;%&#62;&#60;/h2&#62;&#160;&#60;p&#62;统计信息:&#60;br/&#62;共有&#60;%=&#160;@project.tasks.count&#160;%&#62;个&#60;%=link_to&#160;'任务',&#160;project_tasks_path(@project)%&#62;，&#160;已完成&#60;%=&#160;@project.completed_tasks.length&#160;%&#62;个任务。&#160;&#60;hr/&#62;&#160;&#60;h3&#62;最新未完成的5个任务&#60;/h3&#62;&#160;&#60;table&#62;&#160;&#160;&#160;&#60;tr&#62;&#160;&#160;&#160;&#160;&#160;&#60;th&#160;width="25%"&#62;任务名&#60;/th&#62;&#160;&#160;&#160;&#160;&#160;&#60;th&#160;width="75%"&#62;任务摘要&#60;/th&#62;&#160;&#160;&#160;&#60;/tr&#62;&#160;&#160;&#160;&#60;%&#160;for&#160;task&#160;in&#160;@project.tasks.incompleted&#160;%&#62;&#160;&#160;&#160;&#160;&#160;&#60;tr&#62;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;td&#62;&#60;%=&#160;link_to&#160;task.name,&#160;project_task_path(@project,task)&#160;%&#62;&#60;/td&#62;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;td&#62;&#60;%=&#160;task.content&#160;%&#62;&#60;/td&#62;&#160;&#160;&#160;&#160;&#160;&#60;/tr&#62;&#160;&#160;&#160;&#60;%&#160;end&#160;%&#62;&#160;&#60;/table&#62;
来看看log吧：
  Project Load Including Associations (0.000595)   SELECT `projects`.`id` AS t0_r0, `projects`.`title` AS t0_r1, `projects`.`description` AS t0_r2, `projects`.`created_at` AS t0_r3, `projects`.`updated_at` AS t0_r4, `articles`.`id` AS t1_r0, `articles`.`subject` AS t1_r1, `articles`.`summary` AS t1_r2, `articles`.`content` AS t1_r3, `articles`.`project_id` AS t1_r4, `articles`.`created_at` AS t1_r5, `articles`.`updated_at` AS t1_r6, `articles`.`lock_version` AS [...]]]></description>
			<content:encoded><![CDATA[<p>Eager Loading是ActiveRecord的一个数据查询的优化措施，在查询model的时候连同它的关联对象都全查询出来（通过一条包含LEFT OUTER JOIN的SQL语句）。但是在你使用了Eager Loading后，如果还是用一些会触发数据库本身的统计函数的查询方法（如count，average等）的话，那前面的Eager Loading就白费了。下面给出例子：<span id="more-63"></span></p>
<p>两个Model，Project和Task，关系是Project has_many Task。</p>
<p>在ProjectController的show中：<br />
<code>@project&nbsp;=&nbsp;Project.find(params[:id],&nbsp;:include&nbsp;=&gt;&nbsp;[:articles,&nbsp;:tasks])</code></p>
<p>这是project/show页面：<br />
<code>&lt;h1&gt;&lt;%=h&nbsp;@project.title&nbsp;%&gt;&lt;/h1&gt;&nbsp;&lt;h2&gt;&lt;%=h&nbsp;@project.description&nbsp;%&gt;&lt;/h2&gt;&nbsp;&lt;p&gt;统计信息:&lt;br/&gt;共有&lt;%=&nbsp;@project.tasks.count&nbsp;%&gt;个&lt;%=link_to&nbsp;'任务',&nbsp;project_tasks_path(@project)%&gt;，&nbsp;已完成&lt;%=&nbsp;@project.completed_tasks.length&nbsp;%&gt;个任务。&nbsp;&lt;hr/&gt;&nbsp;&lt;h3&gt;最新未完成的5个任务&lt;/h3&gt;&nbsp;&lt;table&gt;&nbsp;&nbsp;&nbsp;&lt;tr&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&nbsp;width="25%"&gt;任务名&lt;/th&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&nbsp;width="75%"&gt;任务摘要&lt;/th&gt;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;&nbsp;&nbsp;&nbsp;&lt;%&nbsp;for&nbsp;task&nbsp;in&nbsp;@project.tasks.incompleted&nbsp;%&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;%=&nbsp;link_to&nbsp;task.name,&nbsp;project_task_path(@project,task)&nbsp;%&gt;&lt;/td&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;%=&nbsp;task.content&nbsp;%&gt;&lt;/td&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;&nbsp;&nbsp;&nbsp;&lt;%&nbsp;end&nbsp;%&gt;&nbsp;&lt;/table&gt;</code></p>
<p>来看看log吧：</p>
<blockquote><p>  Project Load Including Associations (0.000595)   SELECT `projects`.`id` AS t0_r0, `projects`.`title` AS t0_r1, `projects`.`description` AS t0_r2, `projects`.`created_at` AS t0_r3, `projects`.`updated_at` AS t0_r4, `articles`.`id` AS t1_r0, `articles`.`subject` AS t1_r1, `articles`.`summary` AS t1_r2, `articles`.`content` AS t1_r3, `articles`.`project_id` AS t1_r4, `articles`.`created_at` AS t1_r5, `articles`.`updated_at` AS t1_r6, `articles`.`lock_version` AS t1_r7, `tasks`.`id` AS t2_r0, `tasks`.`name` AS t2_r1, `tasks`.`content` AS t2_r2, `tasks`.`completed` AS t2_r3, `tasks`.`project_id` AS t2_r4, `tasks`.`created_at` AS t2_r5, `tasks`.`updated_at` AS t2_r6 FROM `projects` LEFT OUTER JOIN `articles` ON articles.project_id = projects.id LEFT OUTER JOIN `tasks` ON tasks.project_id = projects.id WHERE (`projects`.`id` = 2)<br />
Rendering template within layouts/application<br />
Rendering projects/show<br />
  SQL (0.000255)   SELECT count(*) AS count_all FROM `tasks` WHERE (tasks.project_id = 2) </p></blockquote>
<p>可以看到在Project的Eager Loading的查询之后可以看到又有一个count()的select查询进行了。那前面的Eager Loading的效果似乎没有了。再试试把count方法调用改为调用length方法，这时就看不到另外的那个count()查询了。</p>
<p>这个可能在写代码的时候不会太留意，不过这对性能的影响还是有些的，如果Eager Loading后不会在调用统计函数就ok了。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/03/13/after-eager-loading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>四级通过</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/03/06/%e5%9b%9b%e7%ba%a7%e9%80%9a%e8%bf%87/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/03/06/%e5%9b%9b%e7%ba%a7%e9%80%9a%e8%bf%87/#comments</comments>
		<pubDate>Thu, 06 Mar 2008 05:08:46 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/03/06/%e5%9b%9b%e7%ba%a7%e9%80%9a%e8%bf%87/</guid>
		<description><![CDATA[四级在第二次考试通过了。没什么感觉。不过查询成绩那个网站的js有些问题，由于它是用js检查准考证号，对于FF来说和其他的（Opera和IE）数组下标计算方法不同，FF下总是会提示准考证号长度错误，由于它是发起Ajax调用进行查询的所以不能强制提交，最多绕开浏览器手动用curl提交。。。
]]></description>
			<content:encoded><![CDATA[<p>四级在第二次考试通过了。没什么感觉。不过查询成绩那个网站的js有些问题，由于它是用js检查准考证号，对于FF来说和其他的（Opera和IE）数组下标计算方法不同，FF下总是会提示准考证号长度错误，由于它是发起Ajax调用进行查询的所以不能强制提交，最多绕开浏览器手动用curl提交。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/03/06/%e5%9b%9b%e7%ba%a7%e9%80%9a%e8%bf%87/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails2.0的内嵌资源</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/03/02/rails20%e7%9a%84%e5%86%85%e5%b5%8c%e8%b5%84%e6%ba%90/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/03/02/rails20%e7%9a%84%e5%86%85%e5%b5%8c%e8%b5%84%e6%ba%90/#comments</comments>
		<pubDate>Sun, 02 Mar 2008 08:40:15 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/03/02/rails20%e7%9a%84%e5%86%85%e5%b5%8c%e8%b5%84%e6%ba%90/</guid>
		<description><![CDATA[Rails2.0中提供了一套更好的嵌套资源的处理方法（更加形象化）。

比如有两个model:
# app/model/project.rb
class Project &#60; ActiveRecord::Base
  has_many :tasks
end
# app/model/task.rb
class Task &#60; ActiveRecord::Base
  belongs_to :project
end
在migrate中可以用referece类型来表示引用外键，比如在创建task的migrate中

    create_table :tasks do &#124;t&#124;
      ...
      t.references :project
      ...
    end

路由规则定义如下：
# config/routes.rb
ActionController::Routing::Routes.draw do &#124;map&#124;
  map.resources :projects do &#124;project&#124;
   [...]]]></description>
			<content:encoded><![CDATA[<p>Rails2.0中提供了一套更好的嵌套资源的处理方法（更加形象化）。<br />
<span id="more-62"></span><br />
比如有两个model:<br />
<code># app/model/project.rb<br />
class Project &lt; ActiveRecord::Base<br />
  has_many :tasks<br />
end<br />
# app/model/task.rb<br />
class Task &lt; ActiveRecord::Base<br />
  belongs_to :project<br />
end</code></p>
<p>在migrate中可以用referece类型来表示引用外键，比如在创建task的migrate中<br />
<code><br />
    create_table :tasks do |t|<br />
      ...<br />
      t.references :project<br />
      ...<br />
    end<br />
</code></p>
<p>路由规则定义如下：<br />
<code># config/routes.rb<br />
ActionController::Routing::Routes.draw do |map|<br />
  map.resources :projects do |project|<br />
    project.resources :tasks<br />
  end<br />
end</code></p>
<p>比较好的一个方法调用Task所属Project的方法是用before_filter调用一个方法来设置：<br />
<code>class ArticlesController &lt; ApplicationController<br />
  before_filter :load_project<br />
  ...<br />
  def load_project<br />
    @project = Project.find params[:project_id]<br />
  end<br />
end</code></p>
<p>把Controller中的涉及内嵌资源的find和new的调用改一下：<br />
<code>@project.tasks.find #=&gt; 代替原来的Tasks.find<br />
@projece.tasks.build #=&gt; 代替原来的Tasks.new</code></p>
<p>还有把Controller中的redirect_to方法的参数修改一下：<br />
<code>redirect_to([@project, @task])</code></p>
<p>那在Task的view中应该做如下处理</p>
<p>在生成表单时，传入一个数组给form_for方法：<br />
<code>form_for([@project, @task])</code></p>
<p>调用TasksController的new方法：<br />
<code>new_project_task_path<br />
# =&gt; domain/projects/:id/tasks/new </code></p>
<p>调用TasksController的show方法：<br />
<code>link_to 'Show', [@project, @task]<br />
# =&gt; domain/projects/:id/tasks/:id</code></p>
<p>调用TasksController的edit方法：<br />
<code>link_to 'Edit' edit_project_task_path<br />
# =&gt; domain/projects/:id/tasks/:id/edit </code><br />
或者<br />
<code>link_to 'Delete', [:edit, @project, @task]<br />
# =&gt; domain/projects/:id/tasks/:id/edit </code></p>
<p>调用TasksController的destory方法：<br />
<code>link_to 'Delete', [@project, @task], :confirm =&gt; 'Are you sure?', :method =&gt; :delete<br />
# =&gt; domain/projects/:id/tasks/:id </code></p>
<p>通过这些方法就能让内嵌资源使用时更加优雅，而不用在导向时指定controller和action，再传入父资源和子资源的id。这些xx_path方法会帮你查找routes.rb的路由定义，然后生成url，当然这一切都是基于Rails2.0提倡的RESTful。</p>
<p>参考文章：<br />
<a href="http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial">http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/03/02/rails20%e7%9a%84%e5%86%85%e5%b5%8c%e8%b5%84%e6%ba%90/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>课程</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/27/%e8%af%be%e7%a8%8b/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/27/%e8%af%be%e7%a8%8b/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 14:06:33 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[大学]]></category>
		<category><![CDATA[数据仓库]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/27/%e8%af%be%e7%a8%8b/</guid>
		<description><![CDATA[这个学期的有几门比较贴近实际的课程（有些废话，因为大三了嘛），比如数据挖掘和数据仓库，分布式系统，和服务器配置。

数据挖掘和数据仓库就是把一些现有的数据进行整合，然后抽取到数据仓库中，之后在作一些分析和报告的技术。其中在前后两个阶段都是难点，都是涉及了领域知识，中间做数据仓库相对简单。第一个阶段就是要对现有数据库中的数据作整合，这整合因为数据不同同步，或数据语义有差别，所以需要对领域知识有一个比较好的理解，然后在输出成元数据。最后一个阶段就是按照需求来作数据分析了，这个也是需要结合领域知识。这个就是大概了吧。
老师讲课讲得不错，很清楚的展示上面讲的东西。其实我很多东西有兴趣，只是限于时间不够精力不够不能学那么多，这个数据仓库也只是了解一下就OK了。
讲到数据库，看了豆瓣的开发者http://www.dbanotes.net/的blog，感觉现在由于长尾，小型数据库也开始受到重视，比如MySQL，风光地被SUN收购了。另，BS Ms的心理又来了：不喜欢Ms的SQL Server，好像学校的老师都是拿这个来作实验和讲课。
]]></description>
			<content:encoded><![CDATA[<p>这个学期的有几门比较贴近实际的课程（有些废话，因为大三了嘛），比如数据挖掘和数据仓库，分布式系统，和服务器配置。<br />
<span id="more-60"></span><br />
数据挖掘和数据仓库就是把一些现有的数据进行整合，然后抽取到数据仓库中，之后在作一些分析和报告的技术。其中在前后两个阶段都是难点，都是涉及了领域知识，中间做数据仓库相对简单。第一个阶段就是要对现有数据库中的数据作整合，这整合因为数据不同同步，或数据语义有差别，所以需要对领域知识有一个比较好的理解，然后在输出成元数据。最后一个阶段就是按照需求来作数据分析了，这个也是需要结合领域知识。这个就是大概了吧。</p>
<p>老师讲课讲得不错，很清楚的展示上面讲的东西。其实我很多东西有兴趣，只是限于时间不够精力不够不能学那么多，这个数据仓库也只是了解一下就OK了。</p>
<p>讲到数据库，看了豆瓣的开发者http://www.dbanotes.net/的blog，感觉现在由于长尾，小型数据库也开始受到重视，比如MySQL，风光地被SUN收购了。另，BS Ms的心理又来了：不喜欢Ms的SQL Server，好像学校的老师都是拿这个来作实验和讲课。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/27/%e8%af%be%e7%a8%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web前端浅见</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/24/web%e5%89%8d%e7%ab%af%e6%b5%85%e8%a7%81/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/24/web%e5%89%8d%e7%ab%af%e6%b5%85%e8%a7%81/#comments</comments>
		<pubDate>Sun, 24 Feb 2008 11:30:05 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/24/web%e5%89%8d%e7%ab%af%e6%b5%85%e8%a7%81/</guid>
		<description><![CDATA[Web前端最终传输到用户浏览器的也就是HTML页面，Css文件，JavaScript文件，图像文件。
HTML页面负责的是基本内容和一点点表现逻辑；Css文件负责页面布局和页面里每个元素的样式；JavaScript文件负责的是页面的一些动态表现逻辑。这好像软件架构中的分层一样，把不同职责的部分分开来。
而在传送到客户浏览器之前，这些Html都还是各种脚本，比如Ruby的就是erb，Java的就是Jsp。都先用编程语言来描述页面的基本内容，一般其中充满了if／else／while（用来对Model中属性的各种输出）。对于Rails来说，最直接就是用Ruby来描述这些，Java呢，很喜欢搞个标签库这种东西，说是方便美工，其实也使页面逻辑更难看懂。
JavaScript负责的动态表现逻辑，一般叫Ajax，用的好的话可以获得用户体验，最近看到China-pub的Ajax就做得不错。Css也是Ajax的一个重要部分，那些什么颜色变化都是通过js来修改页面元素的样式实现的，现在web2.0的观感，也是由Css实现的。像FF的插件Greasemonkey就能用js来修改页面的观感。
好像前端就是这些。
]]></description>
			<content:encoded><![CDATA[<p>Web前端最终传输到用户浏览器的也就是HTML页面，Css文件，JavaScript文件，图像文件。</p>
<p>HTML页面负责的是基本内容和一点点表现逻辑；Css文件负责页面布局和页面里每个元素的样式；JavaScript文件负责的是页面的一些动态表现逻辑。这好像软件架构中的分层一样，把不同职责的部分分开来。</p>
<p>而在传送到客户浏览器之前，这些Html都还是各种脚本，比如Ruby的就是erb，Java的就是Jsp。都先用编程语言来描述页面的基本内容，一般其中充满了if／else／while（用来对Model中属性的各种输出）。对于Rails来说，最直接就是用Ruby来描述这些，Java呢，很喜欢搞个标签库这种东西，说是方便美工，其实也使页面逻辑更难看懂。</p>
<p>JavaScript负责的动态表现逻辑，一般叫Ajax，用的好的话可以获得用户体验，最近看到China-pub的Ajax就做得不错。Css也是Ajax的一个重要部分，那些什么颜色变化都是通过js来修改页面元素的样式实现的，现在web2.0的观感，也是由Css实现的。像FF的插件Greasemonkey就能用js来修改页面的观感。</p>
<p>好像前端就是这些。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/24/web%e5%89%8d%e7%ab%af%e6%b5%85%e8%a7%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>很好很快速的Arch(含笔记)</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/22/%e5%be%88%e5%a5%bd%e5%be%88%e5%bf%ab%e9%80%9f%e7%9a%84arch/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/22/%e5%be%88%e5%a5%bd%e5%be%88%e5%bf%ab%e9%80%9f%e7%9a%84arch/#comments</comments>
		<pubDate>Fri, 22 Feb 2008 01:17:22 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Arch]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/22/%e5%be%88%e5%a5%bd%e5%be%88%e5%bf%ab%e9%80%9f%e7%9a%84arch/</guid>
		<description><![CDATA[花了两天的时间才能安装配置好Arch的桌面，虽然很久但是觉得挺值得的。
进gnome桌面的速度很快，一闪就初始化好了面板，很好很强大，其他的软件感觉也快了，不知是不是心理作用。不过还剩下自动挂载U盘没有解决，还有gvim的配色混乱。
作下笔记：
关于MySQL的：
Arch的MySQL 5.0.51-3软件包中有bug，安装后须先修改/usr/share/mysql/mysql_system_tables_data.sql，找到这行：
INSERT INTO tmp_user (host,user) VALUES (@@hostname,);
将INSERT改为REPLACE后保存，再运行初始化脚本。 
然后再设置编码，在／etc／my.conf加上：
a. [client]
default-character-set = utf8

b. [mysqld]
default-character-set = utf8
init-connect = ‘SET NAMES UTF8′
之后执行/etc/rc.d/mysqld start启动，再运行mysql_secure_installation 设置一下。
今年的Linux课程，老师竟然选了《鸟哥的私房菜》，不错。
]]></description>
			<content:encoded><![CDATA[<p>花了两天的时间才能安装配置好Arch的桌面，虽然很久但是觉得挺值得的。<span id="more-57"></span></p>
<p>进gnome桌面的速度很快，一闪就初始化好了面板，很好很强大，其他的软件感觉也快了，不知是不是心理作用。不过还剩下自动挂载U盘没有解决，还有gvim的配色混乱。</p>
<p>作下笔记：</p>
<p>关于MySQL的：</p>
<blockquote><p>Arch的MySQL 5.0.51-3软件包中有bug，安装后须先修改/usr/share/mysql/mysql_system_tables_data.sql，找到这行：</p>
<pre>INSERT INTO tmp_user (host,user) VALUES (@@hostname,);</pre>
<p>将INSERT改为REPLACE后保存，再运行初始化脚本。 </p>
<p>然后再设置编码，在／etc／my.conf加上：</p>
<pre>a. [client]
default-character-set = utf8

b. [mysqld]
default-character-set = utf8
init-connect = ‘SET NAMES UTF8′</pre>
<p>之后执行/etc/rc.d/mysqld start启动，再运行mysql_secure_installation 设置一下。</p></blockquote>
<p>今年的Linux课程，老师竟然选了《鸟哥的私房菜》，不错。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/22/%e5%be%88%e5%a5%bd%e5%be%88%e5%bf%ab%e9%80%9f%e7%9a%84arch/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>寒假结束</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/20/%e5%af%92%e5%81%87%e7%bb%93%e6%9d%9f/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/20/%e5%af%92%e5%81%87%e7%bb%93%e6%9d%9f/#comments</comments>
		<pubDate>Wed, 20 Feb 2008 15:33:55 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[假期]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/20/%e5%af%92%e5%81%87%e7%bb%93%e6%9d%9f/</guid>
		<description><![CDATA[回到学校，一个月的寒假就这样结束了。
放假做了什么？放假的计划完成了吗？放假有没有作些有意义的事？
放假看完了励志经典《高效能人士的七个习惯》，收获不少。很多书都是看到一半，比如《JavaScript高级程序设计》，《Ajax基础教程》，《RESTful web server》，《编写有效用例》。主要时间还是在研究wiki，blog，BBS这些web应用的特征。完成了那个翻译的发布站，感觉上好像一个没什么实际作用的应用，只是把文章分为翻译的状态不同（），再加上一个版本控制，而且都还没有富客户端编辑器。好像很失败，回到学校后自己看了看删了。不过自己做了一个简单的查询单词（用金山词霸在线的词典），和一个小小的BBS，只是有简单的发帖，回复功能。感觉要做到产品级的话就要能做出像基于PHP的Wordpress那样管理功能强大，又说到这个真的很想试用下google的blogger。剩下的时间都是在搞CSS，现在能自己弄出一个类似Ruby on Rails主页的那个界面，能弄出有些web2.0风格的界面。
本来放假里准备读英语和做做一些运动的，可是因为一开始就感冒了一个多星期，这些东西也就进行了两三天，到了感冒好了之后又没有继续。行动力真是差。后来回家的习惯又是发作，每天都睡到中午才起床，几次还睡了一整天，在学校时都是一点睡七点起床的标准作息。
职业规划在这个假期也完成了大部分，自己喜欢做什么，能做什么，希望做什么都是统一的。而在这条道路上，要怎么做，在什么时间要做什么。这些都大概有了计划。也看了一些公司的资料，有在找自己希望就职的公司。
这个放假买了*nway的洗洁精，回家洗碗。还有换了家里洗手盆的进排水管。还算是做了些有贡献的事：）
好像放假很多时间都是在睡觉，很多时间都浪费了。
]]></description>
			<content:encoded><![CDATA[<p>回到学校，一个月的寒假就这样结束了。<br />
放假做了什么？放假的计划完成了吗？放假有没有作些有意义的事？<span id="more-55"></span></p>
<p>放假看完了励志经典《高效能人士的七个习惯》，收获不少。很多书都是看到一半，比如《JavaScript高级程序设计》，《Ajax基础教程》，《RESTful web server》，《编写有效用例》。主要时间还是在研究wiki，blog，BBS这些web应用的特征。完成了那个翻译的发布站，感觉上好像一个没什么实际作用的应用，只是把文章分为翻译的状态不同（），再加上一个版本控制，而且都还没有富客户端编辑器。好像很失败，回到学校后自己看了看删了。不过自己做了一个简单的查询单词（用金山词霸在线的词典），和一个小小的BBS，只是有简单的发帖，回复功能。感觉要做到产品级的话就要能做出像基于PHP的Wordpress那样管理功能强大，又说到这个真的很想试用下google的blogger。剩下的时间都是在搞CSS，现在能自己弄出一个类似Ruby on Rails主页的那个界面，能弄出有些web2.0风格的界面。</p>
<p>本来放假里准备读英语和做做一些运动的，可是因为一开始就感冒了一个多星期，这些东西也就进行了两三天，到了感冒好了之后又没有继续。行动力真是差。后来回家的习惯又是发作，每天都睡到中午才起床，几次还睡了一整天，在学校时都是一点睡七点起床的标准作息。</p>
<p>职业规划在这个假期也完成了大部分，自己喜欢做什么，能做什么，希望做什么都是统一的。而在这条道路上，要怎么做，在什么时间要做什么。这些都大概有了计划。也看了一些公司的资料，有在找自己希望就职的公司。</p>
<p>这个放假买了*nway的洗洁精，回家洗碗。还有换了家里洗手盆的进排水管。还算是做了些有贡献的事：）</p>
<p>好像放假很多时间都是在睡觉，很多时间都浪费了。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/20/%e5%af%92%e5%81%87%e7%bb%93%e6%9d%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>最近多新闻。。。</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/16/%e6%9c%80%e8%bf%91%e5%a4%9a%e6%96%b0%e9%97%bb%e3%80%82%e3%80%82%e3%80%82/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/16/%e6%9c%80%e8%bf%91%e5%a4%9a%e6%96%b0%e9%97%bb%e3%80%82%e3%80%82%e3%80%82/#comments</comments>
		<pubDate>Sat, 16 Feb 2008 09:08:01 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[something]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/16/%e6%9c%80%e8%bf%91%e5%a4%9a%e6%96%b0%e9%97%bb%e3%80%82%e3%80%82%e3%80%82/</guid>
		<description><![CDATA[最近新闻好多啊。
最近好多好多新闻，春节前后，很多人都还在忙活。雅虎忙着被收购，微软忙着收购，，美国忙着大选，，俄罗斯忙着把飞机开到日本领空，，台湾忙着大选，，香港警方忙着抓发照片的，艺人忙着删照片，媒体们忙着炒照片，，各地还忙着收拾大雪残局。。。
今天还在网上看到有消息称Nv想要收购AMD，如果真的成了，Intel就又要有得忙活了，收了之后一统显卡市场对抗准备出产独显的Intel。其实Intel在显卡市场也厉害，他卖出的集显比Nv和Ati的独显卡还多，就像Nokia卖出的集成在手机的数码相机比那些专卖数码相机的厂商的出货量还大。这个道理和MS卖Windows的道理差不多。
这年头新闻的可看性比不上评论的可看性，动漫的可看性比不上动漫迷们的YY。不雅照事件，经过广大的网民YY之后，有了对联，谜语，古诗，剧本等等等等。。。有句话叫广大劳动人民的创造力是无限的。
]]></description>
			<content:encoded><![CDATA[<p>最近新闻好多啊。</p>
<p>最近好多好多新闻，春节前后，很多人都还在忙活。雅虎忙着被收购，微软忙着收购，，美国忙着大选，，俄罗斯忙着把飞机开到日本领空，，台湾忙着大选，，香港警方忙着抓发照片的，艺人忙着删照片，媒体们忙着炒照片，，各地还忙着收拾大雪残局。。。</p>
<p>今天还在网上看到有消息称Nv想要收购AMD，如果真的成了，Intel就又要有得忙活了，收了之后一统显卡市场对抗准备出产独显的Intel。其实Intel在显卡市场也厉害，他卖出的集显比Nv和Ati的独显卡还多，就像Nokia卖出的集成在手机的数码相机比那些专卖数码相机的厂商的出货量还大。这个道理和MS卖Windows的道理差不多。</p>
<p>这年头新闻的可看性比不上评论的可看性，动漫的可看性比不上动漫迷们的YY。不雅照事件，经过广大的网民YY之后，有了对联，谜语，古诗，剧本等等等等。。。有句话叫广大劳动人民的创造力是无限的。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/16/%e6%9c%80%e8%bf%91%e5%a4%9a%e6%96%b0%e9%97%bb%e3%80%82%e3%80%82%e3%80%82/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pacman使用笔记</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/14/usepacman/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/14/usepacman/#comments</comments>
		<pubDate>Thu, 14 Feb 2008 07:57:46 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Arch]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/14/usepacman/</guid>
		<description><![CDATA[pacman是什么，就是和apt-get之于Ubuntu一样，pacman就是Arch的apt-get。

熟悉一下几个pacman的几个常用命令
pacman -S packagename #安装软件包
pacman -R packagename #删除软件包
pacman -Syu #升级系统中的所有包
pacman -Ss package #查询软件包
pacman -Qs package #查询已安装的包
pacman -Sw package #下载但不安装包
pacman -U /path/package.pkg.tar.gz #安装本地包
pacman -Scc #清理包缓存
pacman -Sf pacman #重新安装包
其实要容易记的话可以自己在bashrc里配置一下alias就好。
再说说包下载的提速。。。
修改一下/etc/pacman.conf，把下面这句的注释去掉：
XferCommand = /usr/bin/wget -c --passive-ftp -c %u
这样就可以使用wget来下载包。
也可以用aria2，在配置文件中加上这句：
XferCommand = /usr/bin/aria2c -s 4 -m 2 -d / -o %o %u
-s后面是连接的服务器数量，-m是线程数。
wiki中提供了另一个脚本，是用aria2下载的。
在wiki中还提供了几个包查询彩色输出的脚本。
pacman也有GUI前端，不过我还没有见过用过，过几天回学校就会用上的。
Java interfaces:
    * jacman A nice Java-based interface. 
GTK2/Gnome interfaces:
 [...]]]></description>
			<content:encoded><![CDATA[<p>pacman是什么，就是和apt-get之于Ubuntu一样，pacman就是Arch的apt-get。<br />
<span id="more-53"></span><br />
熟悉一下几个pacman的几个常用命令<br />
<code>pacman -S packagename #安装软件包<br />
pacman -R packagename #删除软件包<br />
pacman -Syu #升级系统中的所有包<br />
pacman -Ss package #查询软件包<br />
pacman -Qs package #查询已安装的包<br />
pacman -Sw package #下载但不安装包<br />
pacman -U /path/package.pkg.tar.gz #安装本地包<br />
pacman -Scc #清理包缓存<br />
pacman -Sf pacman #重新安装包</code></p>
<p>其实要容易记的话可以自己在bashrc里配置一下alias就好。</p>
<p>再说说包下载的提速。。。<br />
修改一下/etc/pacman.conf，把下面这句的注释去掉：<br />
<code>XferCommand = /usr/bin/wget -c --passive-ftp -c %u</code><br />
这样就可以使用wget来下载包。</p>
<p>也可以用aria2，在配置文件中加上这句：<br />
<code>XferCommand = /usr/bin/aria2c -s 4 -m 2 -d / -o %o %u</code><br />
-s后面是连接的服务器数量，-m是线程数。</p>
<p>wiki中提供了<a href="http://wiki.archlinux.org/index.php/Improve_Pacman_Performance">另一个脚本</a>，是用aria2下载的。</p>
<p>在wiki中还<a href="http://wiki.archlinux.org/index.php/Colored_Pacman_output">提供了几个包查询彩色输出的脚本</a>。</p>
<p>pacman也有GUI前端，不过我还没有见过用过，过几天回学校就会用上的。</p>
<blockquote><p>Java interfaces:</p>
<p>    * jacman A nice Java-based interface. </p>
<p>GTK2/Gnome interfaces:</p>
<p>    * gtkpacman Pygtk gui to ArchLinux pacman. An -svn version is available as well (gtkpacman-svn).<br />
    * alunn Tray notifications of new updates and news from Arch front page.<br />
    * guzuta Yet another PyGTK frontend.<br />
    * pacmon-svn Tray applet that notifies the user of available pacman updates. </p>
<p>KDE/Qt interfaces:</p>
<p>    * pacmanager-svn Qt4 package manager based on pacman.<br />
    * kpacupdate Pacman update notification tool for the KDE system tray. </p></blockquote>
<p>之后就慢慢研究一下启动加载的模块，然后在编译一下内核，Arch好好玩。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/14/usepacman/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>今天起，双系统</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/13/beginarch/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/13/beginarch/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 06:15:24 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Arch]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/13/beginarch/</guid>
		<description><![CDATA[近来看到很多人在玩Arch Linux，好像满好玩的，我也去看了看Arch的wiki，发现满好玩的。其实本来想装个Gentoo的，不过看到很多人都说很难忍它的编译时间，遂换Arch。现在就是Arch和Ubuntu双系统啦。

Arch和Gentoo差不多，都是接近*BSD风格的，把很多的配置都塞到几个文件中。安装的时候觉得很快，家里的电脑，安装了基本的系统也只是用了15分钟左右的时间。因为硬盘上已经有了Ubuntu，所以在安装软件包的时候要不选lilo和grub，之后再配置一下grub的menu.lst就OK了。说到引导一开始我是像一般的Linux发行版那样(网上的教程也是这么写)：
title	Arch Linux
root	    (hd0,0)
kernel    /vmlinuz26 root=/dev/sda8 ro
initrd	     /initrd26.img
quiet
弄了半天，grub一直报error15，找不到文件。到/boot看了一下，其实应该把initrd26.img改为kernel26.img。重启一下，OK。
运行pppoe-setup然后再pppoe-start联网，开始升级，发现真的如很多人说的，太慢了，一开始都是在10K/s上下徘徊，见事不对，记得好像在wiki上有一篇是pacman提速的文章，这篇文章里，有讲到把pacman的下载方式改为用其它下载工具的方法，但文章中提示要把pacman升级到最新版，那就忍一下，看看书等升级好。升级很慢而且好像把系统里的所有包都升了，我下载的是core-2007.08的iso，果然软件的升级很快。
升级完后改一下pacman的配置，用aria2c从多个服务器下载来加速软件包的下载，方法会在另一篇post中写出来。不过就算是用这种方法下载速度还是很慢，也就是120K/s上下。没有国内源，也没有第三方镜像，软件包的下载速度果然和Ubuntu没得比。因为很慢所以就安装了浏览器links，一边下载软件包一边可以上Arch的wiki上看看文章。
接着就是要安装桌面环境，安装xorg，gnome包和gnome-extra包，因为家里是Ati的集显X200，所以显卡难配，装了xf86-ati驱动之后进桌面就花了，还是回学校再弄一下，学校电脑的nv卡还是比较好配。
如果Ubuntu有了i686版本的话，或许我会用Ubuntu做平时工作的平台。Ubuntu桌面环境的傻瓜和友好是很多发行版比得上的，只是包太多太杂。Ubuntu不允许多个版本的软件包并存，而且默认对软件包的优化也不够，看看这个：
-rw-r--r-- 1 root root  424317 2008-02-12 18:39 abi-2.6.22-14-generic
-rw-r--r-- 1 root root   75311 2008-02-12 18:39 config-2.6.22-14-generic
-rw-r--r-- 1 root root 7233219 2008-02-16 01:30 initrd.img-2.6.22-14-generic
-rw-r--r-- 1 root root   80021 2008-02-14 02:22 kconfig26
-rw-r--r-- 1 root root 4716941 [...]]]></description>
			<content:encoded><![CDATA[<p>近来看到很多人在玩Arch Linux，好像满好玩的，我也去看了看<a href="http://wiki.archlinux.org/">Arch的wiki</a>，发现满好玩的。其实本来想装个Gentoo的，不过看到很多人都说很难忍它的编译时间，遂换Arch。现在就是Arch和Ubuntu双系统啦。<br />
<span id="more-52"></span><br />
Arch和Gentoo差不多，都是接近*BSD风格的，把很多的配置都塞到几个文件中。安装的时候觉得很快，家里的电脑，安装了基本的系统也只是用了15分钟左右的时间。因为硬盘上已经有了Ubuntu，所以在安装软件包的时候要不选lilo和grub，之后再配置一下grub的menu.lst就OK了。说到引导一开始我是像一般的Linux发行版那样(网上的教程也是这么写)：<br />
<code>title	Arch Linux<br />
root	    (hd0,0)<br />
kernel    /vmlinuz26 root=/dev/sda8 ro<br />
initrd	     /initrd26.img<br />
quiet</code><br />
弄了半天，grub一直报error15，找不到文件。到/boot看了一下，其实应该把initrd26.img改为kernel26.img。重启一下，OK。</p>
<p>运行pppoe-setup然后再pppoe-start联网，开始升级，发现真的如很多人说的，太慢了，一开始都是在10K/s上下徘徊，见事不对，记得好像在wiki上有一篇是pacman提速的文章，这篇文章里，有讲到把pacman的下载方式改为用其它下载工具的方法，但文章中提示要把pacman升级到最新版，那就忍一下，看看书等升级好。升级很慢而且好像把系统里的所有包都升了，我下载的是core-2007.08的iso，果然软件的升级很快。</p>
<p>升级完后改一下pacman的配置，用aria2c从多个服务器下载来加速软件包的下载，方法会在另一篇post中写出来。不过就算是用这种方法下载速度还是很慢，也就是120K/s上下。没有国内源，也没有第三方镜像，软件包的下载速度果然和Ubuntu没得比。因为很慢所以就安装了浏览器links，一边下载软件包一边可以上Arch的wiki上看看文章。</p>
<p>接着就是要安装桌面环境，安装xorg，gnome包和gnome-extra包，因为家里是Ati的集显X200，所以显卡难配，装了xf86-ati驱动之后进桌面就花了，还是回学校再弄一下，学校电脑的nv卡还是比较好配。</p>
<p>如果Ubuntu有了i686版本的话，或许我会用Ubuntu做平时工作的平台。Ubuntu桌面环境的傻瓜和友好是很多发行版比得上的，只是包太多太杂。Ubuntu不允许多个版本的软件包并存，而且默认对软件包的优化也不够，看看这个：<br />
<code>-rw-r--r-- 1 root root  424317 2008-02-12 18:39 abi-2.6.22-14-generic<br />
-rw-r--r-- 1 root root   75311 2008-02-12 18:39 config-2.6.22-14-generic<br />
-rw-r--r-- 1 root root 7233219 2008-02-16 01:30 initrd.img-2.6.22-14-generic<br />
-rw-r--r-- 1 root root   80021 2008-02-14 02:22 kconfig26<br />
-rw-r--r-- 1 root root 4716941 2008-02-14 02:23 kernel26-fallback.img<br />
-rw-r--r-- 1 root root 1658157 2008-02-14 02:23 kernel26.img<br />
-rw-r--r-- 1 root root  103204 2007-09-28 18:06 memtest86+.bin<br />
-rw-r--r-- 1 root root  845769 2008-02-10 23:23 System.map26<br />
-rw-r--r-- 1 root root  823535 2008-02-12 18:39 System.map-2.6.22-14-generic<br />
-rw-r--r-- 1 root root 1861784 2008-02-10 23:23 vmlinuz26<br />
-rw-r--r-- 1 root root 1764536 2008-02-12 18:39 vmlinuz-2.6.22-14-generic<br />
</code><br />
对比一下引导程序的尺寸，差好多。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/13/beginarch/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>一日一D（1）</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/10/%e4%b8%80%e6%97%a5%e4%b8%80dd%ef%bc%881%ef%bc%89/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/10/%e4%b8%80%e6%97%a5%e4%b8%80dd%ef%bc%881%ef%bc%89/#comments</comments>
		<pubDate>Sun, 10 Feb 2008 10:32:43 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[D Language]]></category>
		<category><![CDATA[D语言]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/10/%e4%b8%80%e6%97%a5%e4%b8%80dd%ef%bc%881%ef%bc%89/</guid>
		<description><![CDATA[通过D语言的项目主页dsource.org上的基础教程，来学习D语言吧。。。
D语言已经到了2.0，DMD也到了2.0a，不过很多项目还是只支持到DMD1.0。不过也可以用另一个编译器GNU的DGC。D语言有两个标准库，默认C风格的Phobos和C++风格的Tango。更多的项目都是基于Tango开发的，一些基于Phobos的项目也开始向着Tango转移。从这里可以看出D语言的主要受众是原C/C++的用户。
这次有三个示例代码，三个示例：

第一个是Helloworld
import std.stdio;
&#160;&#160;
void main() {
&#160;&#160;nbspwritef("Hello");
}

可以看到这里用的是std.stdio中的输出方法writef()，一个很类似C的printf的方法，可以对输出进行格式化。
第二个示例展示的是代码的赋值，传统的类C式风格。
import std.stdio;
&#160;&#160;
int magicNumber = 42;
char[6u] password = "sesame";
void main() {
&#160;&#160;writefln("Magic number: ", magicNumber);
&#160;&#160;writefln("Password: ", password);
}

这里要注意的是由于D语言是原生支持utf8的，所以在数组中可以使用nu这样的数量表示。
第三个例子是展示D语言的数据类型。
import std.stdio;
&#160;&#160;
int main() {
&#160;&#160;// Show information about integer types...
&#160;&#160;writefln("bool\tmin: %d\tmax: %d (%d)", bool.min, bool.max, bool.sizeof);
&#160;&#160;writefln("ubyte\tmin: %d\tmax: %d (%d)", ubyte.min, ubyte.max, ubyte.sizeof);
&#160;&#160;writefln("ushort\tmin: %d\tmax: %d (%d)", ushort.min, ushort.max, ushort.sizeof);
&#160;&#160;writefln("uint\tmin: %d\tmax: %d (%d)", uint.min, uint.max, uint.sizeof);
&#160;&#160;writefln("ulong\tmin: %d\tmax: %d (%d)\n", ulong.min, ulong.max, [...]]]></description>
			<content:encoded><![CDATA[<p>通过D语言的项目主页dsource.org上的基础教程，来学习D语言吧。。。</p>
<p>D语言已经到了2.0，DMD也到了2.0a，不过很多项目还是只支持到DMD1.0。不过也可以用另一个编译器GNU的DGC。D语言有两个标准库，默认C风格的Phobos和C++风格的Tango。更多的项目都是基于Tango开发的，一些基于Phobos的项目也开始向着Tango转移。从这里可以看出D语言的主要受众是原C/C++的用户。</p>
<p>这次有三个示例代码，三个示例：<br />
<span id="more-50"></span><br />
第一个是Helloworld<br />
<code>import std.stdio;<br />
&nbsp;&nbsp;<br />
void main() {<br />
&nbsp;&nbsp;nbspwritef("Hello");<br />
}<br />
</code><br />
可以看到这里用的是<a href="http://www.digitalmars.com/d/2.0/phobos/std_stdio.html">std.stdio</a>中的输出方法writef()，一个很类似C的printf的方法，可以对输出进行格式化。</p>
<p>第二个示例展示的是代码的赋值，传统的类C式风格。<br />
<code>import std.stdio;<br />
&nbsp;&nbsp;<br />
int magicNumber = 42;<br />
char[6u] password = "sesame";<br />
void main() {<br />
&nbsp;&nbsp;writefln("Magic number: ", magicNumber);<br />
&nbsp;&nbsp;writefln("Password: ", password);<br />
}<br />
</code><br />
这里要注意的是由于D语言是原生支持utf8的，所以在数组中可以使用nu这样的数量表示。</p>
<p>第三个例子是展示D语言的数据类型。<br />
<code>import std.stdio;<br />
&nbsp;&nbsp;<br />
int main() {<br />
&nbsp;&nbsp;// Show information about integer types...<br />
&nbsp;&nbsp;writefln("bool\tmin: %d\tmax: %d (%d)", bool.min, bool.max, bool.sizeof);<br />
&nbsp;&nbsp;writefln("ubyte\tmin: %d\tmax: %d (%d)", ubyte.min, ubyte.max, ubyte.sizeof);<br />
&nbsp;&nbsp;writefln("ushort\tmin: %d\tmax: %d (%d)", ushort.min, ushort.max, ushort.sizeof);<br />
&nbsp;&nbsp;writefln("uint\tmin: %d\tmax: %d (%d)", uint.min, uint.max, uint.sizeof);<br />
&nbsp;&nbsp;writefln("ulong\tmin: %d\tmax: %d (%d)\n", ulong.min, ulong.max, ulong.sizeof);<br />
&nbsp;&nbsp;writefln("byte\tmin: %d\tmax: %d (%d)", byte.min, byte.max, byte.sizeof);<br />
&nbsp;&nbsp;writefln("short\tmin: %d\tmax: %d (%d)", short.min, short.max, short.sizeof);<br />
&nbsp;&nbsp;writefln("int\tmin: %d\tmax: %d (%d)", int.min, int.max, int.sizeof);<br />
&nbsp;&nbsp;writefln("long\tmin: %d\tmax: %d (%d)\n", long.min, long.max, long.sizeof);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;// Show information about floating-point types...<br />
&nbsp;&nbsp;writef("float (%d)\tdouble (%d)\treal (%d)\t", float.sizeof, double.sizeof, real.sizeof);<br />
&nbsp;&nbsp;writef("ifloat (%d)\tidouble (%d)\tireal (%d)\t", ifloat.sizeof, idouble.sizeof, ireal.sizeof);<br />
&nbsp;&nbsp;writef("cfloat (%d)\tcdouble (%d)\tcreal (%d)\t", cfloat.sizeof, cdouble.sizeof, creal.sizeof);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;// Show information about character types...<br />
&nbsp;&nbsp;writef("char (%d)\twchar (%d)\tdchar (%d)\t", char.sizeof, wchar.sizeof, dchar.sizeof);<br />
&nbsp;&nbsp;return 0;<br />
}<br />
</code><br />
这里就看到了std.stdio.writefln()方法的格式化功能。每种数据类型都有min和max，sizeof属性，这就是D语言的特性之一的原生属性支持（现代面向对象思想）。其中，浮点数里以i开头的表示复数中的虚部，以c开头就是复数，没有前缀的就是实数，而float，double，real的精度逐渐递减，c开头的浮点数类型的长度是无前缀的和以i开头的浮点数的长度之和。字符中，无前缀的char是utf8编码的，8位，w开头的wchar是utf16的，16位，d开头的dchar是utf32，32位。具体的D语言的数据类型可以参看<a href="http://www.digitalmars.com/d/2.0/type.html">D语言规范中关于数据类型的部分</a>。</p>
<p>可以看到D语言的语句还是比较面熟的，是最流行的C风格。在之后的“一日一DD”中会继续看代码学D语言的。</p>
<p>代码来自<a href="http://www.dsource.org/projects/tutorials/wiki/TutorialFundamentals">TutorialFundamentals</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/10/%e4%b8%80%e6%97%a5%e4%b8%80dd%ef%bc%881%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>几个shell快捷键</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/10/%e5%87%a0%e4%b8%aashell%e5%bf%ab%e6%8d%b7%e9%94%ae/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/10/%e5%87%a0%e4%b8%aashell%e5%bf%ab%e6%8d%b7%e9%94%ae/#comments</comments>
		<pubDate>Sun, 10 Feb 2008 08:19:16 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/10/%e5%87%a0%e4%b8%aashell%e5%bf%ab%e6%8d%b7%e9%94%ae/</guid>
		<description><![CDATA[有点菜鸟向了，有了这几个快捷键就能和很多视频里的高手那样高速地在shell上编辑命令。。。

[Ctrl + r]查找和执行历史命令
[Ctrl + p] 或 [Ctrl + n] 快速向前或向后滚动查找一个历史命令
[Ctrl + a] 跳转至命令行首    Ahead of line
[Ctrl + e] 跳转至命令行尾    End of line
[Ctrl + f] 向前跳转一个字符  jump Forward one character
[Ctrl + b] 向后跳转一个字符  jump Backward one character
[Alt + f] 向前跳转到下一个字的第一个字符
[Alt + b] 向后跳转到下一个字的第一个字符
[Ctrl + w] 向后删除一个字，用来对付刚刚输入的错误字很有用
[Ctrl + u] [...]]]></description>
			<content:encoded><![CDATA[<p>有点菜鸟向了，有了这几个快捷键就能和很多视频里的高手那样高速地在shell上编辑命令。。。<br />
<span id="more-49"></span></p>
<blockquote><p>[Ctrl + r]查找和执行历史命令<br />
[Ctrl + p] 或 [Ctrl + n] 快速向前或向后滚动查找一个历史命令</p></blockquote>
<blockquote><p>[Ctrl + a] 跳转至命令行首    Ahead of line<br />
[Ctrl + e] 跳转至命令行尾    End of line</p>
<p>[Ctrl + f] 向前跳转一个字符  jump Forward one character<br />
[Ctrl + b] 向后跳转一个字符  jump Backward one character</p>
<p>[Alt + f] 向前跳转到下一个字的第一个字符<br />
[Alt + b] 向后跳转到下一个字的第一个字符</p></blockquote>
<blockquote><p>[Ctrl + w] 向后删除一个字，用来对付刚刚输入的错误字很有用</p>
<p>[Ctrl + u] 从光标当前位置删除所有字符至行首<br />
[Ctrl + k] 从光标当前位置删除所有字符至行尾</p>
<p>[Ctrl + d] 删除光标当前位置的字符</p>
<p>[Ctrl + y] 粘贴最后一个被删除的字</p>
<p>[Alt + d] 删除从光标当前位置，到当前字的结尾字符</p></blockquote>
<blockquote><p>Ctrl + l 相当于clear 命令</p></blockquote>
<p>注意，在GUI下记得把shell的Alt+f快捷键打开菜单栏的选项关掉。。。</p>
<p>参考自：<a href="http://www.linuxsir.org/main/node/151">《快速编辑 Shell 命令行》</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/10/%e5%87%a0%e4%b8%aashell%e5%bf%ab%e6%8d%b7%e9%94%ae/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>完成Blog搬家</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/09/%e5%ae%8c%e6%88%90blog%e6%90%ac%e5%ae%b6/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/09/%e5%ae%8c%e6%88%90blog%e6%90%ac%e5%ae%b6/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 21:17:12 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/09/%e5%ae%8c%e6%88%90blog%e6%90%ac%e5%ae%b6/</guid>
		<description><![CDATA[终于逃离了x-space的魔爪之下，不过还是会使用之前那个blog的，毕竟比较常去那里（ruby-lang.org.cn）。
Blog搬家的感受挺多的，我的Blog一开始是在msn space上，之后就是在BlogJava，后来到了ruby-lang.org.cn（x-space）。我的日志越写越多，越写越能写出些有价值东西（相对论，其实现在写的也很多东西很废，慢慢写慢慢会写）。一边搬家一边看着自己以前写过的日志，感触挺深的。感觉自己长大了，学习了。。。
现在在这里写日志知道怎么办了，贴代码的时候要自己手工加空格（nbsp;），我的code标签的样式是抄ee的，黑底白字的block。
这次搬家的手法比较弱智，是手工一篇一篇搬的，一来是x-sapce不支持输出，二来是自己懒得去研究怎么要把x-sapce的日志导出。。。
下一步要做的就是美化一下这里，改下主题（牢骚一下），写些页面，写下自我介绍。看到标签云真开心。接着可以开始写我的vim和d语言的日志了（本来这几天要写的，就是忙着Blog搬家），ohoh~~
最后一句废话：年轻人选择Blog要慎重，要知道自己的需求是什么，要找个能导出导入（方便搬家），能选择RSS输出的格式的。。。
]]></description>
			<content:encoded><![CDATA[<p>终于逃离了x-space的魔爪之下，不过还是会使用之前<a href="http://rc.org.cn/?uid/1352">那个blog</a>的，毕竟比较常去那里（ruby-lang.org.cn）。<span id="more-48"></span></p>
<p>Blog搬家的感受挺多的，我的Blog一开始是在msn space上，之后就是在BlogJava，后来到了ruby-lang.org.cn（x-space）。我的日志越写越多，越写越能写出些有价值东西（相对论，其实现在写的也很多东西很废，慢慢写慢慢会写）。一边搬家一边看着自己以前写过的日志，感触挺深的。感觉自己长大了，学习了。。。</p>
<p>现在在这里写日志知道怎么办了，贴代码的时候要自己手工加空格（nbsp;），我的code标签的样式是抄ee的，黑底白字的block。</p>
<p>这次搬家的手法比较弱智，是手工一篇一篇搬的，一来是x-sapce不支持输出，二来是自己懒得去研究怎么要把x-sapce的日志导出。。。</p>
<p>下一步要做的就是美化一下这里，改下主题（牢骚一下），写些页面，写下自我介绍。看到标签云真开心。接着可以开始写我的vim和d语言的日志了（本来这几天要写的，就是忙着Blog搬家），ohoh~~</p>
<p>最后一句废话：年轻人选择Blog要慎重，要知道自己的需求是什么，要找个能导出导入（方便搬家），能选择RSS输出的格式的。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/09/%e5%ae%8c%e6%88%90blog%e6%90%ac%e5%ae%b6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>原来这xspace是贼船</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/08/%e5%8e%9f%e6%9d%a5%e8%bf%99xspace%e6%98%af%e8%b4%bc%e8%88%b9/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/08/%e5%8e%9f%e6%9d%a5%e8%bf%99xspace%e6%98%af%e8%b4%bc%e8%88%b9/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 12:57:54 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/08/%e5%8e%9f%e6%9d%a5%e8%bf%99xspace%e6%98%af%e8%b4%bc%e8%88%b9/</guid>
		<description><![CDATA[由于对X-space的不满持续升级，所以越来越想把Blog搬出去，至少能备份到一个具有标准api的blog系统中。忽然发现xspace不能把日志导出，而且其RSS没有全文输出，输出数量也有限，哇靠，太垄断了。。。导出的RSS的编码不是utf8，是gbk。。。
在网上搜索了一下，能够支持xspace导出的有一个程序，blogbak，试着用了一下，发现这是刚下了一贼船又上另一贼船，虽然的确可以导出xspace的文章出来，但是导出的blog文件只能在它的支持商51XXX上导入。。。
看来要好好看看RSS2.0和Atom的规范还有blogger的api。。。还有把自己的全部文章手动导出来一下。。。
]]></description>
			<content:encoded><![CDATA[<p>由于对X-space的不满持续升级，所以越来越想把Blog搬出去，至少能备份到一个具有标准api的blog系统中。<span id="more-39"></span>忽然发现xspace不能把日志导出，而且其RSS没有全文输出，输出数量也有限，哇靠，太垄断了。。。导出的RSS的编码不是utf8，是gbk。。。</p>
<p>在网上搜索了一下，能够支持xspace导出的有一个程序，blogbak，试着用了一下，发现这是刚下了一贼船又上另一贼船，虽然的确可以导出xspace的文章出来，但是导出的blog文件只能在它的支持商51XXX上导入。。。</p>
<p>看来要好好看看RSS2.0和Atom的规范还有blogger的api。。。还有把自己的全部文章手动导出来一下。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/08/%e5%8e%9f%e6%9d%a5%e8%bf%99xspace%e6%98%af%e8%b4%bc%e8%88%b9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>过年同学会</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/08/%e8%bf%87%e5%b9%b4%e5%90%8c%e5%ad%a6%e4%bc%9a/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/08/%e8%bf%87%e5%b9%b4%e5%90%8c%e5%ad%a6%e4%bc%9a/#comments</comments>
		<pubDate>Thu, 07 Feb 2008 16:00:15 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[假期]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/08/%e8%bf%87%e5%b9%b4%e5%90%8c%e5%ad%a6%e4%bc%9a/</guid>
		<description><![CDATA[今晚去和高中同学聚了一下。许多同学都是出来工作了，我因为复读一年，本科四年，和当时读高中的同学就有了两年的差距。
发现有些女生已经嫁了，有些还有孩子了。最近要结婚的一个同学，嫁了一个月收入5W以上的人，这让我什么都说不出。。。貌似现在做销售的就是社会的高薪人士，有些不服气，这些在广州深圳收入过W的人，现在买楼买房，很轻松，哪里想刚刚毕业的学生，几千块的月薪还要扣20%的税，扣完之后你还能剩多少？女生就是嫁得好就好了，有些刚毕业就有人娶的基本不用奋斗了，所以有人说女生要成功直接嫁给Gates就好了。
我呢，还是在花父母的钱的学生仔，去实习，去工作之还要再花父母多少钱，还要奋斗几年才能娶女朋友，还有要奋斗几年才能实现自己的梦想，感觉自己的梦想好像幻想。。。
不行，我要努力。。。要给老婆幸福，要给父母幸福，要实现自己的梦想。。。
第一要努力，第二还是要努力，第三还是要努力。。。
drive2me大哥的意见

享受努力的过程是一大幸福。有些人走捷径就没有这种乐趣。
本来人生就是来享受过程的。对吧。
没有什么可以比的，走自己的路，对自己负责，就好了。
有些幸福的永恒的，而有些是短暂的，把握自己的人才能把握自己的幸福。依靠别人幸福的人，不会永久幸福的。

]]></description>
			<content:encoded><![CDATA[<p>今晚去和高中同学聚了一下。许多同学都是出来工作了，我因为复读一年，本科四年，和当时读高中的同学就有了两年的差距。<span id="more-40"></span></p>
<p>发现有些女生已经嫁了，有些还有孩子了。最近要结婚的一个同学，嫁了一个月收入5W以上的人，这让我什么都说不出。。。貌似现在做销售的就是社会的高薪人士，有些不服气，这些在广州深圳收入过W的人，现在买楼买房，很轻松，哪里想刚刚毕业的学生，几千块的月薪还要扣20%的税，扣完之后你还能剩多少？女生就是嫁得好就好了，有些刚毕业就有人娶的基本不用奋斗了，所以有人说女生要成功直接嫁给Gates就好了。</p>
<p>我呢，还是在花父母的钱的学生仔，去实习，去工作之还要再花父母多少钱，还要奋斗几年才能娶女朋友，还有要奋斗几年才能实现自己的梦想，感觉自己的梦想好像幻想。。。</p>
<p>不行，我要努力。。。要给老婆幸福，要给父母幸福，要实现自己的梦想。。。</p>
<p>第一要努力，第二还是要努力，第三还是要努力。。。</p>
<p>drive2me大哥的意见</p>
<blockquote><p>
享受努力的过程是一大幸福。有些人走捷径就没有这种乐趣。<br />
本来人生就是来享受过程的。对吧。</p>
<p>没有什么可以比的，走自己的路，对自己负责，就好了。</p>
<p>有些幸福的永恒的，而有些是短暂的，把握自己的人才能把握自己的幸福。依靠别人幸福的人，不会永久幸福的。
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/08/%e8%bf%87%e5%b9%b4%e5%90%8c%e5%ad%a6%e4%bc%9a/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>翻版完全使用Linux工作</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/03/%e7%bf%bb%e7%89%88%e5%ae%8c%e5%85%a8%e4%bd%bf%e7%94%a8linux%e5%b7%a5%e4%bd%9c/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/03/%e7%bf%bb%e7%89%88%e5%ae%8c%e5%85%a8%e4%bd%bf%e7%94%a8linux%e5%b7%a5%e4%bd%9c/#comments</comments>
		<pubDate>Sun, 03 Feb 2008 10:19:13 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Thinking]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/03/%e7%bf%bb%e7%89%88%e5%ae%8c%e5%85%a8%e4%bd%bf%e7%94%a8linux%e5%b7%a5%e4%bd%9c/</guid>
		<description><![CDATA[此文抄袭兼模仿http://www.cqacmm.com/myweb/teach/workinlinux.htm
下午闲着无事，又跑到Ubuntu论坛的吵架版看猴子戏，并且自己也过了一回当猴子的瘾。。。
用Ubuntu下半年了，感觉回到win下有种别扭的感觉。有个喜欢重装suse的同学问我，你平时用Linux做什么？我那时愣了一下，想想回答说，上网。。。

在12月底时就把硬盘中win在玩了一次实况之后删了，因为又用不到win了所以删了。现在在VBox里开win也是上网银或者改doc（在永中里编辑后看看有没有问题）。
最近才看了LFS和Gentoo的文档，知道了它们是怎么安装的，好像都是满麻烦的，把系统里每个部分，包括基本的内核，常用的工具，每个核心的库都自己编译出来。虽然麻烦但是真正的自定义Linux，真正的是玩Linux。有些人说自己整出一个LFS可以用一辈子。。。
现在开始有空的时候就用Ubuntu的apt-get source来自己编译软件和每个库，一个一个编译构建包，试试感觉，等以后换个Gentoo做准备。
其实用什么OS，自己喜欢就好。我想用Linux就用嘛。
我就是喜欢用Linux，因为编码是utf8，因为有多个实用Unix工具，因为写代码的时候完全用鼠标，因为平时WM操作的时候可以尽量不用鼠标，因为不会中病毒，因为不用时不时就清理系统，因为不用重装系统，因为在不同的电脑上只要把硬盘插上就可以用。。。
]]></description>
			<content:encoded><![CDATA[<p>此文抄袭兼模仿http://www.cqacmm.com/myweb/teach/workinlinux.htm</p>
<p>下午闲着无事，又跑到Ubuntu论坛的吵架版看猴子戏，并且自己也过了一回当猴子的瘾。。。</p>
<p>用Ubuntu下半年了，感觉回到win下有种别扭的感觉。有个喜欢重装suse的同学问我，你平时用Linux做什么？我那时愣了一下，想想回答说，上网。。。<br />
<span id="more-41"></span><br />
在12月底时就把硬盘中win在玩了一次实况之后删了，因为又用不到win了所以删了。现在在VBox里开win也是上网银或者改doc（在永中里编辑后看看有没有问题）。</p>
<p>最近才看了LFS和Gentoo的文档，知道了它们是怎么安装的，好像都是满麻烦的，把系统里每个部分，包括基本的内核，常用的工具，每个核心的库都自己编译出来。虽然麻烦但是真正的自定义Linux，真正的是玩Linux。有些人说自己整出一个LFS可以用一辈子。。。</p>
<p>现在开始有空的时候就用Ubuntu的apt-get source来自己编译软件和每个库，一个一个编译构建包，试试感觉，等以后换个Gentoo做准备。</p>
<p>其实用什么OS，自己喜欢就好。我想用Linux就用嘛。</p>
<p>我就是喜欢用Linux，因为编码是utf8，因为有多个实用Unix工具，因为写代码的时候完全用鼠标，因为平时WM操作的时候可以尽量不用鼠标，因为不会中病毒，因为不用时不时就清理系统，因为不用重装系统，因为在不同的电脑上只要把硬盘插上就可以用。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/03/%e7%bf%bb%e7%89%88%e5%ae%8c%e5%85%a8%e4%bd%bf%e7%94%a8linux%e5%b7%a5%e4%bd%9c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>很好很强大的VIM4Ruby</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/02/03/%e5%be%88%e5%a5%bd%e5%be%88%e5%bc%ba%e5%a4%a7%e7%9a%84vim4ruby/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/02/03/%e5%be%88%e5%a5%bd%e5%be%88%e5%bc%ba%e5%a4%a7%e7%9a%84vim4ruby/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 16:44:05 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/02/03/%e5%be%88%e5%a5%bd%e5%be%88%e5%bc%ba%e5%a4%a7%e7%9a%84vim4ruby/</guid>
		<description><![CDATA[今天终于找到了最后一个插件，Ruby Snippets，终于打造出自己觉得最强Ruby开发利器的Vim，写下来记下来。。。
Ruby Snippets的演示：
http://eustaquiorangel.com/blog/show/438
Rails.vim的演示：
http://www.youtube.com/watch?v=3 &#8230; ls%20testing%20ruby

我的插件列表：
vim-ruby gem install vim-ruby &#8211;remote &#38;&#38; vim-ruby-install.rb
rails.vim
http://www.vim.org/scripts/script.php?script_id=1567
rubysnippets
http://www.vim.org/scripts/script.php?script_id=1966
project
http://www.vim.org/scripts/script.php?script_id=69
NERD_tree
http://www.vim.org/scripts/script.php?script_id=1658
bufexplorer
http://www.vim.org/scripts/script.php?script_id=42
taglist
http://www.vim.org/scripts/script.php?script_id=273
winmanager
http://www.vim.org/scripts/script.php?script_id=95
matchit
http://www.vim.org/scripts/script.php?script_id=39
svncommand
http://www.vim.org/scripts/script.php?script_id=922
surround
http://www.vim.org/scripts/script.php?script_id=1697
supertab
http://www.vim.org/scripts/script.php?script_id=1643
加上上面的插件后，VIM就很好很强大，有rails.vim（目前支持Rails2.0）的跳转和快捷的rake执行等等的优点不用多说了，而vim- ruby则提供了高亮和代码补全等，今天找到的Ruby Snippets就实现了类似Textmate的模板补全（让我眼红了很久的功能）。nerd-tree和bufexplorer，winmanager 组成了一个代码浏览文件浏览的强大功能，svncommand和surround分别提供了svn支持和标签补全。。。
这样的VIM真是很好很强大。。。
上图：

参考的资料：
http://wiki.rubyonrails.org/rails/pages/HowtoUseVimWithRails
http://www.upulife.com/leo/?p=191
http://www.upulife.com/leo/?p=196
http://blog.csdn.net/wooin/archive/2007/10/31/1858917.aspx
]]></description>
			<content:encoded><![CDATA[<p>今天终于找到了最后一个插件，Ruby Snippets，终于打造出自己觉得最强Ruby开发利器的Vim，写下来记下来。。。</p>
<p>Ruby Snippets的演示：<br />
<a href="http://eustaquiorangel.com/blog/show/438">http://eustaquiorangel.com/blog/show/438</a></p>
<p>Rails.vim的演示：<br />
<a href="http://www.youtube.com/watch?v=30P8DSNOZuU&amp;mode=related&amp;search=rcov%20rails%20testing%20ruby">http://www.youtube.com/watch?v=3 &#8230; ls%20testing%20ruby</a><br />
<span id="more-5"></span><br />
我的插件列表：</p>
<p>vim-ruby gem install vim-ruby &#8211;remote &amp;&amp; vim-ruby-install.rb<br />
rails.vim<br />
<a href="http://www.vim.org/scripts/script.php?script_id=1567">http://www.vim.org/scripts/script.php?script_id=1567</a><br />
rubysnippets<br />
<a href="http://www.vim.org/scripts/script.php?script_id=1966">http://www.vim.org/scripts/script.php?script_id=1966</a><br />
project<br />
<a href="http://www.vim.org/scripts/script.php?script_id=69">http://www.vim.org/scripts/script.php?script_id=69</a><br />
NERD_tree<br />
<a href="http://www.vim.org/scripts/script.php?script_id=1658">http://www.vim.org/scripts/script.php?script_id=1658</a><br />
bufexplorer<br />
<a href="http://www.vim.org/scripts/script.php?script_id=42">http://www.vim.org/scripts/script.php?script_id=42</a><br />
taglist<br />
<a href="http://www.vim.org/scripts/script.php?script_id=273">http://www.vim.org/scripts/script.php?script_id=273</a><br />
winmanager<br />
<a href="http://www.vim.org/scripts/script.php?script_id=95">http://www.vim.org/scripts/script.php?script_id=95</a><br />
matchit<br />
<a href="http://www.vim.org/scripts/script.php?script_id=39">http://www.vim.org/scripts/script.php?script_id=39</a><br />
svncommand<br />
<a href="http://www.vim.org/scripts/script.php?script_id=922">http://www.vim.org/scripts/script.php?script_id=922</a><br />
surround<br />
<a href="http://www.vim.org/scripts/script.php?script_id=1697">http://www.vim.org/scripts/script.php?script_id=1697</a><br />
supertab<br />
<a href="http://www.vim.org/scripts/script.php?script_id=1643">http://www.vim.org/scripts/script.php?script_id=1643</a></p>
<p>加上上面的插件后，VIM就很好很强大，有rails.vim（目前支持Rails2.0）的跳转和快捷的rake执行等等的优点不用多说了，而vim- ruby则提供了高亮和代码补全等，今天找到的Ruby Snippets就实现了类似Textmate的模板补全（让我眼红了很久的功能）。nerd-tree和bufexplorer，winmanager 组成了一个代码浏览文件浏览的强大功能，svncommand和surround分别提供了svn支持和标签补全。。。</p>
<p>这样的VIM真是很好很强大。。。</p>
<p>上图：</p>
<p><img src="http://ruby-lang.org.cn/forums/attachments/month_0802/20080203_215faadbbaa0aa3e0d92RmplWRMwwMsQ.png" border="0" /></p>
<p>参考的资料：<br />
<a href="http://wiki.rubyonrails.org/rails/pages/HowtoUseVimWithRails">http://wiki.rubyonrails.org/rails/pages/HowtoUseVimWithRails</a><br />
<a href="http://www.upulife.com/leo/?p=191">http://www.upulife.com/leo/?p=191</a><br />
<a href="http://www.upulife.com/leo/?p=196">http://www.upulife.com/leo/?p=196</a><br />
<a href="http://blog.csdn.net/wooin/archive/2007/10/31/1858917.aspx">http://blog.csdn.net/wooin/archive/2007/10/31/1858917.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/02/03/%e5%be%88%e5%a5%bd%e5%be%88%e5%bc%ba%e5%a4%a7%e7%9a%84vim4ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]来自Rails Envy的Rails Cache教程 part1</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part1/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part1/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 14:21:36 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part1/</guid>
		<description><![CDATA[原文来自Rails Envy http://railsenvy.com/2007/2/28/rails-caching-tutorial
整个教程有两部份，第一部分也就是这篇讲page cache，第二篇讲其它的cache。这篇文章其实主要还是讲基础，不过结合了一些示例，并配上生动的语言。
 合适的缓存机制可以提升Rails应用的性能。而Page Cache就是Rails中最高效的缓存。Page Cahe机制可以让每次请求不用进行数据库查询，甚至不用触动到Ruby解析器，完全由前端web服务器来进行服务。
 配置
 如果你想在devlopment模式启用cache机制，就需要修改 /config/environments/development.rb文件，找到下面这行并把配置项改为true：
config.action_controller.perform_caching = true
页面缓存
 两种很适合缓存页面的情况： 
 
当页面对于所有用户都是相同的 
当页面是公开的，而且无须用户认证 

 假设环境是在一个不经常改动的Blog页面中。。。Controller的代码应该貌似这样：
class BlogController &#60; ApplicationController
&#160;&#160;def list
&#160; &#160;&#160;&#160;Post.find(:all, :order =&#62; "created_on desc", :limit =&#62; 10)
&#160;&#160;end
&#160;&#160;...
如果想要缓存list action中显示的页面就在代码中加入：
class BlogController &#60; ApplicationController
&#160; &#160;caches_page :list
&#160;&#160;
&#160; &#160;def list
&#160; &#160;&#160;&#160;Post.find(:all, :order =&#62; "created_on desc", :limit =&#62; 10)
&#160; &#160;end
&#160;&#160;...
这样，在下次请求时就会生成并返回缓存好的list.html页面，下下次的话就是直接返回缓存页面。 如果使用的是mongrel，对list action进行配置后的第一次请求时，/logs/development.log会有貌似以下的记录：
Processing BlogController#list (for 127.0.0.1 at 2007-02-23 00:58:56) [...]]]></description>
			<content:encoded><![CDATA[<p>原文来自Rails Envy<br /> <a href="http://railsenvy.com/2007/2/28/rails-caching-tutorial">http://railsenvy.com/2007/2/28/rails-caching-tutorial</a><br />
整个教程有两部份，第一部分也就是这篇讲page cache，第二篇讲其它的cache。这篇文章其实主要还是讲基础，不过结合了一些示例，并配上生动的语言。</p>
<p> 合适的缓存机制可以提升Rails应用的性能。而Page Cache就是Rails中最高效的缓存。Page Cahe机制可以让每次请求不用进行数据库查询，甚至不用触动到Ruby解析器，完全由前端web服务器来进行服务。<span id="more-42"></span></p>
<p> <b>配置</b></p>
<p> 如果你想在devlopment模式启用cache机制，就需要修改<b> /config/environments/development.rb</b>文件，找到下面这行并把配置项改为true：<br />
<code>config.action_controller.perform_caching = true</code><br />
<b>页面缓存</b></p>
<p> 两种很适合缓存页面的情况：<br /> 
<ol> 
<li>当页面对于所有用户都是相同的 </li>
<li>当页面是公开的，而且无须用户认证 </li>
</ol>
<p> 假设环境是在一个不经常改动的Blog页面中。。。Controller的代码应该貌似这样：<br />
<code>class BlogController &lt; ApplicationController<br />
&nbsp;&nbsp;def list<br />
&nbsp; &nbsp;&nbsp;&nbsp;Post.find(:all, :order =&gt; "created_on desc", :limit =&gt; 10)<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;...</code><br />
如果想要缓存list action中显示的页面就在代码中加入：<br />
<code>class BlogController &lt; ApplicationController<br />
&nbsp; &nbsp;caches_page :list<br />
&nbsp;&nbsp;<br />
&nbsp; &nbsp;def list<br />
&nbsp; &nbsp;&nbsp;&nbsp;Post.find(:all, :order =&gt; "created_on desc", :limit =&gt; 10)<br />
&nbsp; &nbsp;end<br />
&nbsp;&nbsp;...</code><br />
这样，在下次请求时就会生成并返回缓存好的list.html页面，下下次的话就是直接返回缓存页面。<br /> 如果使用的是mongrel，对list action进行配置后的第一次请求时，/logs/development.log会有貌似以下的记录：<br />
<code>Processing BlogController#list (for 127.0.0.1 at 2007-02-23 00:58:56) [GET]<br />
Parameters: {"action"=&gt;"list", "controller"=&gt;"blog"}<br />
SELECT * FROM posts ORDER BY created_on LIMIT 10<br />
Rendering blog/list<br />
Cached page: /blog/list.html (0.00000)<br />
Completed in 0.18700 (5 reqs/sec) | Rendering: 0.10900 (58%) | DB: 0.00000 (0%) | 200 OK [http://localhost/blog/list]</code><br />
<b>Cached page: /blog/list.html</b>这行记录表明了页面已被导入，并存放在<b> /public/blog/list.html</b> 位置下。在这个文件中没有一丁点Ruby代码。下一次请求到来时又会绕过Rails再次返回这个静态页面，这就提升了效率，降低了服务器的开销。</p>
<p> 这样的话，如果是有动态表单的页面和经常更新的页面，Page Cache就不太适合了。不过还可以采用其它的缓存机制，请留意本教程的Part2。（卖广告:&gt;）<br /> 如果在代码里再加上这一句：<br />
<code>caches_page :show</code><br />
当URL指向<b>/blog/show/5</b>访问id为5的blog日志时，请问调用的是哪个缓存文件（或其文件名为什么）？<br /> 答案是：<b>/public/blog/show/5.html</b><br /> 看看下面的例子（URL和对应的缓存文件）：<br />
<code>http://localhost:3000/blog/list =&gt; /public/blog/list.html<br />
http://localhost:3000/blog/edit/5 =&gt; /public/edit/5.html<br />
http://localhost:3000/blog =&gt; /public/blog.html<br />
http://localhost:3000/ =&gt; /public/index.html<br />
http://localhost:3000/blog/list?page=2 =&gt; /public/blog/list.html</code><br />
伊，等等，不太对阿。第一行和最后一行怎么返回的缓存文件一样？Page Cache忽略了URL附带的参数了。</p>
<p> <b>在采用分页的页面怎么使用Page Cahe</b></p>
<p> 要缓存不同的文件，只能创建不同格式的URL了。使用“<b>/blog/list?page=2</b>”的话会出问题，那就使用“<b>/blog/list/2</b>”吧。这样子的话，数字2就是作为params[:id]了，那就要修改路由规则（<b>/config/routes.rb</b>）了：<br />
<code>map.connect 'blog/list/:page',<br />
&nbsp; &nbsp; :controller =&gt; 'blog',<br />
&nbsp; &nbsp; :action =&gt; 'list',<br />
&nbsp; &nbsp; :requirements =&gt; { :page =&gt; /\d+/},<br />
&nbsp; &nbsp; :page =&gt; nil</code><br />
配合新的路由，页面的链接也要改一下：<br />
<code>&lt;%= link_to "Next Page", :controller =&gt; 'blog', :action =&gt; 'list', :page =&gt; 2 %&gt;</code><br />
上面这句生成的URL就是“<b>/blog/list/2</b>”了，访问这 URL时会以下两件事会发生：<br /> Rails应用把数字2作为params[:page]<br /> 这个页面被缓存为<b>/public/blog/list/2.html</b><br /> 上面这个示例告诉我们，如果要使用PageCache机制的话，那就要对附加参数做一下处理，让附加参数成为URL的一部分。</p>
<p> <b>清理Cache</b></p>
<p> 页面失效了怎么办？那就清理掉失效页面呗！</p>
<p> 以下两行代码可以清除上面例子中生成的Cache：<br />
<code># This will remove /blog/list.html<br />
expire_page(:controller =&gt; 'blog', :action =&gt; 'list')<br />
# This will remove /blog/show/5.html<br />
expire_page(:controller =&gt; 'blog', :action =&gt; 'show', :id =&gt; 5)</code><br />
那就要在每次添加/改动/删除blog日志时都进行这些操作。要把这两行代码加入action中吗？不，有优雅的解决方法。。。</p>
<p> <b>Sweepers</b></p>
<p> Sweepers是一些能在页面失效是删除旧的缓存的代码。Sweepers监视Model的一举一动，当Model进行CRUD时，Sweepers得知后就会去把相应的缓存删除掉。<br /> Sweepers的操作应该放在一个Controller中，而且作者认为还应该与其它的controller分离开。那就要改动配置文件<b>/config/environment.rb</b>：<br />
<code>Rails::Initializer.run do |config|<br />
&nbsp; &nbsp;# ...<br />
&nbsp; &nbsp;config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )<br />
&nbsp; &nbsp;# ...<br />
end</code><br />
友情提示，改动环境变量之后记得重启服务器。</p>
<p> 如上改动后在/app/sweepers创建sweepers，文件<b> /app/sweepers/blog_sweeper.rb</b>应该是这样：<br />
<code>class BlogSweeper &lt; ActionController::Caching::Sweeper<br />
&nbsp;&nbsp;observe Post # This sweeper is going to keep an eye on the Post model<br />
&nbsp;&nbsp;# If our sweeper detects that a Post was created call this<br />
&nbsp;&nbsp;def after_create(post)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; expire_cache_for(post)<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;# If our sweeper detects that a Post was updated call this<br />
&nbsp;&nbsp;def after_update(post)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; expire_cache_for(post)<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;# If our sweeper detects that a Post was deleted call this<br />
&nbsp;&nbsp;def after_destroy(post)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; expire_cache_for(post)<br />
&nbsp;&nbsp;end<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp;private<br />
&nbsp;&nbsp;def expire_cache_for(record)<br />
&nbsp; &nbsp; # Expire the list page now that we posted a new blog entry<br />
&nbsp; &nbsp; expire_page(:controller =&gt; 'blog', :action =&gt; 'list')<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; # Also expire the show page, incase we just edited a blog entry<br />
&nbsp; &nbsp; expire_page(:controller =&gt; 'blog', :action =&gt; 'show', :id =&gt; record.id)&lt;<br />
&nbsp;&nbsp;end<br />
end</code><br />
生成Sweepers可以使用插件Sweeper Generator，可以参看<a href="http://www.ruby-lang.org.cn/forums/thread-1085-1-5.html">martin的介绍</a>。</p>
<p> 友情提示：用after_save方法可以代替上面的after_create和after_update两个方法。<br /> 要调用Sweepers，在文件<b>/app/controllers/BlogController.rb</b>中应这些写代码：<br />
<code>class BlogController &lt; ApplicationController<br />
&nbsp; &nbsp;caches_page :list, :show<br />
&nbsp; &nbsp;cache_sweeper :blog_sweeper, :only =&gt; [:create, :update, :destroy]<br />
&nbsp; &nbsp;...</code><br />
当创建一个Blog日志时，会在<b> logs/development.log</b>中发现这样的记录：<br />
<code>Expired page: /blog/list.html (0.00000)<br />
Expired page: /blog/show/3.html (0.00000)</code><br />
hoho~ sweepers生效了。</p>
<p> <b>在Apache/Lighttpd的漂亮演出</b> </p>
<p> 许多Rails应用都会使用Apache作为前端，用Mongrel / Lighttpd处理动态的RoR请求。要使Rails的Page Cache机制生效，告诉服务器当请求来的时候去哪里查找缓存页面。下面是配置Apache为例，修改<b>httpd.conf</b>文件：<br />
<code>&lt;VirtualHost *:80&gt;<br />
&nbsp;&nbsp;...<br />
&nbsp;&nbsp;# Configure mongrel_cluster<br />
&nbsp;&nbsp;&lt;Proxy balancer://blog_cluster&gt;<br />
&nbsp; &nbsp; BalancerMember [url]http://127.0.0.1:8030[/url]<br />
&nbsp;&nbsp;&lt;/Proxy&gt;<br />
&nbsp;&nbsp;RewriteEngine On<br />
&nbsp;&nbsp;# Rewrite index to check for static<br />
&nbsp;&nbsp;RewriteRule ^/$ /index.html [QSA]<br />
&nbsp;&nbsp;# Rewrite to check for Rails cached page<br />
&nbsp;&nbsp;RewriteRule ^([^.]+)$ $1.html [QSA]<br />
&nbsp;&nbsp;# Redirect all non-static requests to cluster<br />
&nbsp;&nbsp;RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f<br />
&nbsp;&nbsp;RewriteRule ^/(.*)$ balancer://blog_cluster%{REQUEST_URI} [P,QSA,L]<br />
&nbsp;&nbsp;...<br />
&lt;/VirtualHost&gt;</code><br />
在lighttpd中应该是类似这样：<br />
<code>server.modules = ( "mod_rewrite", ... )<br />
url.rewrite += ( "^/$" =&gt; "/index.html" )<br />
url.rewrite += ( "^([^.]+)$" =&gt; "$1.html" )</code><br />
这样代理服务器就会/public目录下查询cache文件，这样你可能会想要修改cache文件的目录。</p>
<p> <b>把Cache文件分离处理</b></p>
<p> 首先这样修改<b>/config/environment.rb</b>：<br />
<code>config.action_controller.page_cache_directory = RAILS_ROOT + "/public/cache/"</code><br />
这样就让Rails在<b>/public/cache/</b> 下生成缓存文件了。接着就修改前端服务器Apache的配置文件<b>httpd.conf</b>：<br />
<code>&nbsp;&nbsp;# Rewrite index to check for static<br />
&nbsp;&nbsp;RewriteRule ^/$ cache/index.html [QSA]<br />
&nbsp;&nbsp;# Rewrite to check for Rails cached page<br />
&nbsp;&nbsp;RewriteRule ^([^.]+)$ cache/$1.html [QSA]</code><br />
<b>清理单个局部或者全部缓存</b></p>
<p> 当开始使用页面缓存的时候可能会发现，一旦对模型有CRUD操作，基本上所有的缓存都要被清除掉。那直接删除了生成的缓存文件岂不是更好更快。</p>
<p> 首先要把cache文件分离出来，这在上一步已经做了。下面的代码直接删除cache文件夹下的所有文件，并记录事件到日志中：<br />
<code>class BlogSweeper &lt; ActionController::Caching::Sweeper<br />
&nbsp;&nbsp;observe Post<br />
&nbsp;&nbsp;def after_save(record)<br />
&nbsp; &nbsp; self.class::sweep<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;def after_destroy(record)<br />
&nbsp; &nbsp; self.class::sweep<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;def self.sweep<br />
&nbsp; &nbsp; cache_dir = ActionController::Base.page_cache_directory<br />
&nbsp; &nbsp; unless cache_dir == RAILS_ROOT+"/public"<br />
&nbsp; &nbsp;&nbsp; &nbsp;FileUtils.rm_r(Dir.glob(cache_dir+"/*")) rescue Errno::ENOENT<br />
&nbsp; &nbsp;&nbsp; &nbsp;RAILS_DEFAULT_LOGGER.info("Cache directory '#{cache_dir}' fully sweeped.")<br />
&nbsp; &nbsp; end<br />
&nbsp;&nbsp;end<br />
end</code><br />
FileUtils.rm_r 方法删除目录下所有文件。这就相当于执行了多次的expire操作。也可以删词cache目录的子目录下的文件，如下面代码展示的对 /public/blog目录下所有文件进行删除：<br />
<code>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;cache_dir = ActionController::Base.page_cache_directory<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;FileUtils.rm_r(Dir.glob(cache_dir+"/blog/*")) rescue Errno::ENOENT</code><br />
<b>更高级的Page Cache技巧？</b></p>
<p> 在大型Web应用中Page Cache的处理将会是非常复杂的。</p>
<p> Rick Olson写了<a href="http://svn.techno-weenie.net/projects/plugins/referenced_page_caching/">Referenced Page Caching Plugin</a>用数据库来对缓存页面进行跟踪。README中有一些示例展示。</p>
<p> Max Dunn写了篇文章<a href="http://blog.maxdunn.com/articles/2006/09/16/ruby-on-rails-advanced-page-caching"> Advanced Page Caching</a>，向我们展示了他如何使用cookies动态地改变页面缓存处理基于用户角色的wiki页面。</p>
<p> 最后，Page Cache还无法解决缓存xml文件，Mike Zornek讲述了这个问题并提出了一些方法，详见<a href="http://clickablebliss.com/blog/2006/02/17/rails_caching_xml_bad_mime_types/">这里</a>。</p>
<p> <b>Page Cache怎么测试？</b></p>
<p> Rails本身并没有提供给我们。Damien Merenne写了一个插件 <a href="http://blog.cosinux.org/pages/page-cache-test">swank plugin</a>试图解决这个问题。试一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>今天整理了一下Msn Spaces</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e4%bb%8a%e5%a4%a9%e6%95%b4%e7%90%86%e4%ba%86%e4%b8%80%e4%b8%8bmsn-spaces/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e4%bb%8a%e5%a4%a9%e6%95%b4%e7%90%86%e4%ba%86%e4%b8%80%e4%b8%8bmsn-spaces/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 17:09:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Thinking]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/31/%e4%bb%8a%e5%a4%a9%e6%95%b4%e7%90%86%e4%ba%86%e4%b8%80%e4%b8%8bmsn-spaces/</guid>
		<description><![CDATA[整理了一下我的msn space：Msn space
删掉了一些废铁，改了一下主题。又发一下牢骚，这里的界面也不好玩，比起wordpress等那些系统来说，可定制性弱很多，又没有什么吸引人的功能，而且速度太慢了，又不支持firefox。
看到以前自己写的，感觉很多东西都很弱智，竟然还傻乎乎贴了一堆抄书帖和转帖，基本上没有自己发现和理解整理的东西。虽然现在也没有太多有创造性的东西写出来，可是有时做做翻译，做做技术整理总结，比以前算是有进步了。一开始初心者很多东西还是在看别人的，慢慢地积累之后才有自己的想法，慢慢地成长。现在回想起来，感觉自己大学这两年多已经对软件开发入了门。该知道的原理不敢说都懂了都理解了，只能说基本都了解，知道自己欠缺什么，应该学习哪些，未来的路子和方向也明朗了。
也看到了自己的感情生活的经历，其实自己的感情也是经历了很多，我希望能和老婆婷婷继续走下去，坚持到毕业，再坚持到能够有地方住，然后就能结婚了。因为现在的楼价物价都是很高的，所以我要更加努力才能养地起一个家。现在才懂事，才知道爸爸妈妈是多么伟大，多么厉害，我的爸爸一个人担负起了整个家的经济收入，我的妈妈一个人负担起了家里大大小小的事情照顾整家人的起居饮食，他们是最伟大的，我爱我的爸爸妈妈。我希望以后能和爸爸一样养起整个家，有能力像妈妈照顾家庭。这些好像是小学生说的话，但是这真的是发自我内心的。
我要每天都比昨天进步，每天有收获，成为一个对社会有用的人。
]]></description>
			<content:encoded><![CDATA[<p>整理了一下我的msn space：<a href="maninred16.spaces.live.com">Msn space</a><span id="more-15"></span></p>
<p>删掉了一些废铁，改了一下主题。又发一下牢骚，这里的界面也不好玩，比起wordpress等那些系统来说，可定制性弱很多，又没有什么吸引人的功能，而且速度太慢了，又不支持firefox。</p>
<p>看到以前自己写的，感觉很多东西都很弱智，竟然还傻乎乎贴了一堆抄书帖和转帖，基本上没有自己发现和理解整理的东西。虽然现在也没有太多有创造性的东西写出来，可是有时做做翻译，做做技术整理总结，比以前算是有进步了。一开始初心者很多东西还是在看别人的，慢慢地积累之后才有自己的想法，慢慢地成长。现在回想起来，感觉自己大学这两年多已经对软件开发入了门。该知道的原理不敢说都懂了都理解了，只能说基本都了解，知道自己欠缺什么，应该学习哪些，未来的路子和方向也明朗了。</p>
<p>也看到了自己的感情生活的经历，其实自己的感情也是经历了很多，我希望能和老婆婷婷继续走下去，坚持到毕业，再坚持到能够有地方住，然后就能结婚了。因为现在的楼价物价都是很高的，所以我要更加努力才能养地起一个家。现在才懂事，才知道爸爸妈妈是多么伟大，多么厉害，我的爸爸一个人担负起了整个家的经济收入，我的妈妈一个人负担起了家里大大小小的事情照顾整家人的起居饮食，他们是最伟大的，我爱我的爸爸妈妈。我希望以后能和爸爸一样养起整个家，有能力像妈妈照顾家庭。这些好像是小学生说的话，但是这真的是发自我内心的。</p>
<p>我要每天都比昨天进步，每天有收获，成为一个对社会有用的人。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e4%bb%8a%e5%a4%a9%e6%95%b4%e7%90%86%e4%ba%86%e4%b8%80%e4%b8%8bmsn-spaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]来自Rails Envy的Rails Cache教程 part2</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part2/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part2/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 16:00:00 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part2/</guid>
		<description><![CDATA[原文地址：http://railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2
本教程的编写顺序是按照各个缓存的效率来排序的，Page缓存最快，所以在第一篇教程就介绍了，这篇教程就介绍其它的几种缓存。

Action 缓存
Action缓存和Page缓存十分相似，唯一的区别就是对页面的请求会触及Rails服务器并且filter还是会运行。类似下面代码这样设置Action缓存：
class BlogController &#60; ApplicationController
&#160;&#160;layout 'base'
&#160;&#160;before_filter :authenticate&#160;&#160;# &#60;--- Check out my authentication
&#160;&#160;caches_action :list, :show
可以从代码中看到，用户必须通过认证才能访问list action，当对list进行请求时可以从 /log/development.log看到如下日志
Processing BlogController#list (for 127.0.0.1 at 2007-03-04 12:51:24) [GET]
Parameters: {"action"=&#62;"list", "controller"=&#62;"blog"}
Checking Authentication
Post Load (0.000000) SELECT * FROM posts ORDER BY created_on LIMIT 10
Rendering blog/list
Cached fragment: localhost:3000/blog/list (0.00000)
Completed in 0.07800 (12 reqs/sec) &#124; Rendering: 0.01600 (20%) &#124; DB: 0.00000 (0%) &#124; 200 [...]]]></description>
			<content:encoded><![CDATA[<p>原文地址：http://railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2</p>
<p>本教程的编写顺序是按照各个缓存的效率来排序的，Page缓存最快，所以在第一篇教程就介绍了，这篇教程就介绍其它的几种缓存。<br />
<span id="more-7"></span><br />
Action 缓存</p>
<p>Action缓存和Page缓存十分相似，唯一的区别就是对页面的请求会触及Rails服务器并且filter还是会运行。类似下面代码这样设置Action缓存：<br />
<code>class BlogController &lt; ApplicationController<br />
&nbsp;&nbsp;layout 'base'<br />
&nbsp;&nbsp;before_filter :authenticate&nbsp;&nbsp;# &lt;--- Check out my authentication<br />
&nbsp;&nbsp;caches_action :list, :show</code></p>
<p>可以从代码中看到，用户必须通过认证才能访问list action，当对list进行请求时可以从 <strong>/log/development.log</strong>看到如下日志<br />
<code>Processing BlogController#list (for 127.0.0.1 at 2007-03-04 12:51:24) [GET]<br />
Parameters: {"action"=&gt;"list", "controller"=&gt;"blog"}<br />
Checking Authentication<br />
Post Load (0.000000) SELECT * FROM posts ORDER BY created_on LIMIT 10<br />
Rendering blog/list<br />
Cached fragment: localhost:3000/blog/list (0.00000)<br />
Completed in 0.07800 (12 reqs/sec) | Rendering: 0.01600 (20%) | DB: 0.00000 (0%) | 200 OK [http://localhost/blog/list]</code><br />
看到“Cached fragment: localhost:3000/blog/list”这行了吗？这表示有缓存文件生成，并且可以找到如下这个文件：<br />
/tmp/cache/localhost:3000/blog/list.cache<br />
默认的情况是， Action缓存会在/tmp/cache/目录下缓存文件，而不是像Page缓存那样直接输出.html文件，是输出.cache文件。如果你在单个应用中包含了一个以上的自域名，缓存文件的路径会包含主机和端口（localhost:3000）。这种情况下每个自域名会缓存在各自的目录下。</p>
<p>如果打开“list.cache”文件，就会看到其中的内容是完整的静态html页面，就像Page缓存的一样。那它们之间有什么区别呢？如果我们再次对页面做出请求（经过上面的请求之后），来看看<strong>/log/development.log</strong>：<br />
<code>Processing BlogController#list (for 127.0.0.1 at 2007-03-04 13:01:31) [GET]<br />
Parameters: {"action"=&gt;"list", "controller"=&gt;"blog"}<br />
Checking Authentication<br />
Fragment read: localhost:3000/blog/list (0.00000)<br />
Completed in 0.00010 (10000 reqs/sec) | DB: 0.00000 (0%) | 200 OK [http://localhost/blog/list]<br />
</code><br />
如你所见， 前置过滤器Authentication执行了，接着读取了缓存文件，然后输出。所以在这个情况下，依然是输出那个完整的缓存文件，并且还做了用户认证的检查。</p>
<p>这里值得注意的是，action执行前前置过滤器必须被执行。另一方面，你也可能会缓存到一个错误的html文件。</p>
<p>怎样清理Action缓存</p>
<p>如教程Part1中，缓存必须在数据发生变化后被清除掉。这里也是用sweepers，只不过在<strong>/app/sweepers/blog_sweeper.rb</strong>中&#8221;expire_page&#8221; 要改为 &#8220;expire_action&#8221;：<br />
<code># Expire the list page now that we posted a new blog entry<br />
expire_action(:controller =&gt; 'blog', :action =&gt; 'list')<br />
# Also expire the show page, incase we just edited a blog entry<br />
expire_action(:controller =&gt; 'blog', :action =&gt; 'show', :id =&gt; record.id)<br />
</code><br />
也可以用以下的rake任务来清除 Action 缓存和 Fragment 缓存：<br />
<code>rake tmp:cache:clear</code><br />
这个rake任务会删除所有的.cache文件。</p>
<p>Fragment Caching</p>
<p>使用了缓存之后会让应用变得飞快，但是由于这是动态的web应用，缓存整个页面并且总能命中这是不实际的，所以有了Fragment缓存。Fragment缓存能缓存页面中的一部分。</p>
<p>要对Blog应用中Post列表进行Fragment进行缓存就要编辑 <strong>/app/views/blog/list.rhtml</strong>：<br />
<code>&lt;strong&gt;My Blog Posts&lt;/strong&gt;<br />
&lt;% cache do %&gt;<br />
&lt;ul&gt;<br />
&lt;% for post in @posts %&gt;<br />
&lt;li&gt;&lt;%= link_to post.title, :controller =&gt; 'blog', :action =&gt; 'show', :id =&gt; post %&gt;&lt;/li&gt;<br />
&lt;% end %&gt;<br />
&lt;/ul&gt;<br />
&lt;% end %&gt;<br />
</code><br />
这段cache do的代码会创建文件/tmp/cache/localhost:3000/blog/list.cache，即使用当前的controller和action来进行命名。当下次请求来到并命中cache do部分的代码时就会读取刚刚说到那个缓存文件。让我们查看<strong>/log/development.log</strong>，来看看第一次和第二次请求中发生了什么：<br />
<code>Processing BlogController#list (for 127.0.0.1 at 2007-03-17 22:02:16) [GET]<br />
Authenticating User<br />
Post Load (0.000230)   SELECT * FROM posts<br />
Rendering blog/list<br />
Cached fragment: localhost:3000/blog/list (0.00267)<br />
Completed in 0.02353 (42 reqs/sec) | Rendering: 0.01286 (54%) | DB: 0.00248 (10%) | 200 OK [http://localhost/blog/list]<br />
Processing BlogController#list (for 127.0.0.1 at 2007-03-17 22:02:17) [GET]<br />
Authenticating User<br />
Post Load (0.000219)   SELECT * FROM posts<br />
Rendering blog/list<br />
Fragment read: localhost:3000/blog/list (0.00024)<br />
Completed in 0.01530 (65 reqs/sec) | Rendering: 0.00545 (35%) | DB: 0.00360 (23%) | 200 OK [http://localhost/blog/list]</code><br />
有没有感觉到一些冗余？<br />
在第一次请求时生成了缓存，第二次时读取缓存，但是对Posts的SQL查询进行了两次。我们已经对SQL查询的结果缓存到页面中了，我们在缓存之后不用再进行SQL查询了，是吗？</p>
<p>解决这个问题的其中的一个方法就是编辑<strong>/controllers/blog_controller.rb</strong>，在查询前加上一个条件检查：<br />
<code>def list<br />
unless read_fragment({})<br />
@post = Post.find(:all, :order =&gt; 'created_on desc', :limit =&gt; 10) %&gt;<br />
end<br />
end</code><br />
现在只会在没有缓存的时候才有查询出现。或者有人会想，把这个请求放到view中的cache do代码块中不就好了吗？但是这个是MVC架构啊。</p>
<p>猜猜怎样清除Fragment缓存</p>
<p><code># Expire the blog list fragment<br />
expire_fragment(:controller =&gt; 'blog', :action =&gt; 'list')</code><br />
没错吧？</p>
<p>在分页中使用Fragment缓存</p>
<p>默认情况下，缓存的命名是通过直接查找当前的controller和action名字来决定的。也就是说controller 为 &#8220;blog&#8221;并且 action 为 &#8220;list&#8221;就会缓存到 &#8220;/localhost:3000/blog/list.cache&#8221;。</p>
<p>在分页的情况下，就要把分页的页码加到缓存文件中。<strong>blog_controller.rb</strong>应该类似下面那样处理：<br />
<code>def list<br />
  unless read_fragment({:page =&gt; params[:page] || 1})  # Add the page param to the cache naming<br />
    @post_pages, @posts = paginate :posts, :per_page =&gt; 10<br />
  end<br />
end</code><br />
在这里代码也可以为：read_fragment({:controller =&gt; &#8216;blog&#8217;, :action =&gt; &#8216;list&#8217;, :page =&gt; params[:page] || 1})，但Rails决定了前两个参数，这个无法改变，所以可以省略。</p>
<p>/views/blog/list.rhtml如下：<br />
<code>&lt;% cache ({:page =&gt; params[:page] || 1}) do %&gt;<br />
...  All of the html to display the posts ...<br />
&lt;% end %&gt;</code><br />
这段代码会在第一次访问 /blog/list时，会创建 /localhost:3000/blog/list.page=1.cache 的缓存文件，按理可知访问分页2时会创建缓存文件/localhost:3000/blog/list.page=2.cache。 Pretty cool!</p>
<p>对Fragment缓存高级命名机制</p>
<p>大多数时候要对cache进行命名，这里有个示例：</p>
<p>话说现代的Web设计中每个页面都有一个用户自定义的导航目录（nav menu）。这里是一个列出用户要完成的项目任务（task）的导航目录：<br />
<code>&lt;div id="nav-bar"&gt;<br />
&lt;strong&gt;Your Tasks&lt;/strong&gt;<br />
&lt;ul&gt;<br />
&lt;% for task in Task.find_by_member_id(session[:user_id]) %&gt;<br />
&lt;li&gt;&lt;%= task.name %&gt;&lt;/li&gt;<br />
&lt;% end %&gt;<br />
&lt;/ul&gt;<br />
&lt;/div&gt;</code><br />
这个会在站点的每个页面中显示，如果能在用户第一次访问页面时缓存起来，在之后的访问就不用总是打扰数据库了。那就要对代码进行一点点改动：<br />
<code>&lt;div id="nav-bar"&gt;<br />
&lt;strong&gt;Your Tasks&lt;/strong&gt;<br />
&lt;% cache (:controller =&gt; "base", :action =&gt; "user_tasks", :user_id =&gt; session[:user_id]) do %&gt;<br />
&lt;ul&gt;<br />
&lt;% for task in Task.find_by_member_id(session[:user_id]) %&gt;<br />
&lt;li&gt;&lt;%= task.name %&gt;&lt;/li&gt;<br />
&lt;% end %&gt;<br />
&lt;/ul&gt;<br />
&lt;% end %&gt;<br />
&lt;/div&gt;</code><br />
当user_id为1时会创建缓存文件/localhost:3000/base/user_tasks.user_id=1.cache。</p>
<p>Fragment缓存命名示例<br />
这里有些用户命名缓存的例子：<br />
<code>cache ("turkey") =&gt; "/tmp/cache/turkey.cache"<br />
cache (:controller =&gt; 'blog', :action =&gt; 'show', :id =&gt; 1) =&gt; "/tmp/cache/localhost:3000/blog/show/1.cache"<br />
cache ("blog/recent_posts") =&gt; "/tmp/cache/blog/recent_posts.cache"<br />
cache ("#{request.host_with_port}/blog/recent_posts") =&gt; "/tmp/cache/localhost:3000/blog/recent_posts.cache"</code><br />
怎样一次sweep多个缓存</p>
<p>上面的分页的Fragment缓存最后生成了很多缓存文件，已知的清除方法只是：<br />
<code>expire_fragment(:controller =&gt; 'blog', :action =&gt; 'list', :page =&gt; 1)<br />
expire_fragment(:controller =&gt; 'blog', :action =&gt; 'list', :page =&gt; 2)<br />
expire_fragment(:controller =&gt; 'blog', :action =&gt; 'list', :page =&gt; 3)<br />
.....</code><br />
但是这里还有一个方法来做这些事情：<br />
<code>expire_fragment(%r{blog/list.*})</code><br />
这样会查找blog/list下的所有cache文件。使用这个方法要明白下面几点：<br />
1. 不能在Memcached（下面会提到）下运行。<br />
2. 这种方法会对所有的cache文件进行正则匹配，如果你的系统中有4,000+个cache文件，这会让你的系统处理很久。<br />
3. 如果你不慎写错了正则表达式，那可能会出大问题。</p>
<p>Action/Fragment缓存的几种缓存机制</p>
<p>Page 缓存只能使用文件系统。Action 和 Fragment缓存就有几种选择：<br />
1. File Store &#8211; (默认) &#8211; 把缓存放在磁盘中 (默认在 /tmp/cache/ 目录)。<br />
2. Memory Store &#8211; Rails服务器的处理方法，放在内存。<br />
3. DRb Store &#8211; 使用DRb服务器。<br />
4. MemCache Store &#8211; MemCache是一个高性能的缓存处理程序。注意它不是用Ruby实现的。</p>
<p>作者认为FileStore是一开始最好的选择，在以后升级为其它的方式（如MemCache）也不难，要改变缓存文件存储的位置可以编辑config/environment.rb：<br />
<code>ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory"</code><br />
ActiveRecord查询缓存</p>
<p>这是第四种缓存机制，对这种机制并没有过多的文档，它只出现在 Rails Edge中，现在来介绍一下。</p>
<p>ActiveRecord并不需要做配置，在默认情况下会自动运行。看看这个action：<br />
<code>class BlogController &lt; ApplicationController<br />
 def some_complex_thing<br />
  post = Post.find(1)<br />
  # .... Do alot of other stuff<br />
  post_again = Post.find(1)<br />
 end<br />
end</code><br />
在没有AR缓存的情况下，SQL查询会进行两次。现在使用了AR缓存后，在第二次的查询会读取第一次查询时生成的缓存。这样就不用担心在单个的Action中两次相同的查询会查询数据库两次了。</p>
<p>不过这里的例子不够直观，但想像复杂的认证代码。很多时候可能会在多种认证方式中进行用户数据的查询，而且这是发布在几个不同地方的代码中的，如果缓存了结果，无疑对性能有提高。</p>
<p>查询缓存在action中第一次查询时缓存，在action结束时清除掉缓存。这里没有真正的存储，当 inserts/updates/deletes 执行时，全部缓存就会刷新。如果你要在多个actions或users间缓存数据，请使用MemCache。</p>
<p>参考：<br /> 关于fragment缓存的失效可以参看martin推荐的<a href="http://www.ruby-lang.org.cn/forums/thread-1701-1-3.html">timed_fragment_cache插件</a><br /> 关于AR的缓存，可以看看<a href="http://ryandaigle.com/articles/2007/2/7/what-s-new-in-edge-rails-activerecord-explicit-caching">这篇文章</a>的，<a href="http://yudionrails.com/2007/12/17/what-s-new-in-edge-rails-activerecord-explicit-caching">这篇文章yudi有翻译</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/30/%e7%bf%bb%e8%af%91%e6%9d%a5%e8%87%aarails-envy%e7%9a%84rails-cache%e6%95%99%e7%a8%8b-part2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails，用户认证</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/28/rails%ef%bc%8c%e7%94%a8%e6%88%b7%e8%ae%a4%e8%af%81/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/28/rails%ef%bc%8c%e7%94%a8%e6%88%b7%e8%ae%a4%e8%af%81/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 14:50:05 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/28/rails%ef%bc%8c%e7%94%a8%e6%88%b7%e8%ae%a4%e8%af%81/</guid>
		<description><![CDATA[最近自己写了写代码，研究了一下关于Rails中用户认证方面的知识。

Rails中的用户认证解决方法，看到大多数是靠插件实现，比如：
LoginGenerator
Acts_as_authenticated
restful_authentication
&#8230;&#8230;
其中采用的方法都类似于《Agile Web 2e》的dopet示例的处理方法：

通过虚拟的password属性来作为密码
通过随机生成的salt和密码明文（或者MD5等方法）加密后存入数据库
在controller中通过before_filter来阻止未通过认证的用户对action进行调用
在view中通过如islogin?，isadmin?等方法来让保护需要登录或者为管理员的行为

插件中一般都是做出一个Model和两个Controller，处理用户数据的User。而Controller，一个负责登录和登出，另一个User的负责用户创建和删除。
关于记住用户状态的实现，大部分用户认证的插件都有。参考User+authentication+in+Ruby+on+Rails：
添加一个cookie_hash字段到user中：
class AddUserCookieHash &#60; ActiveRecord::Migration
&#160;def self.up
&#160;&#160;add_column :users, :cookie_hash, :string
&#160;end
&#160;def self.down
&#160;&#160;remove_column :users, :cookie_hash
&#160;end
end
接着在登录页面，如login.html.erb中，加入：
 remember me
然后在管理login的controller中添加：
def login
&#160;if request.post?
&#160;&#160;@user = User.find_by_username(params[:login])
&#160;&#160;if @user and @user.password_is? params[:password]
&#160;&#160;&#160;session[:uid] = @user.id
&#160;&#160;&#160;# 当用户需要被记住时，开始对cookie进行处理
&#160;&#160;&#160;# 对cookie生成一个密钥之后放入cookie和存入数据库（user表中）
&#160;&#160;&#160;# 其中还指定了一个cookies失效时间，默认为30天，其实可以把这个参数提出来
&#160;&#160;&#160;if params[:remember]
&#160;&#160;&#160;&#160;cookie_pass = [Array.new(9){rand(256).chr}.join].pack("m").chomp
&#160;&#160;&#160;&#160;cookie_hash = Digest::MD5.hexdigest(cookie_pass + &#160;&#160;&#160;&#160;@user.password_salt)
&#160;&#160;&#160;&#160;cookies[:userapp_login_pass] = { :value =&#62; cookie_pass, :expires =&#62; 30.days.from_now }
&#160;&#160;&#160;&#160;cookies[:userapp_login] = { :value =&#62; @user.username, :expires =&#62; 30.days.from_now }
&#160;&#160;&#160;&#160;User.update(@user.id, :cookie_hash =&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>最近自己写了写代码，研究了一下关于Rails中用户认证方面的知识。<br />
<span id="more-8"></span><br />
Rails中的用户认证解决方法，看到大多数是靠插件实现，比如：<br />
LoginGenerator<br />
Acts_as_authenticated<br />
restful_authentication<br />
&#8230;&#8230;</p>
<p>其中采用的方法都类似于《Agile Web 2e》的dopet示例的处理方法：</p>
<ul>
<li>通过虚拟的password属性来作为密码</li>
<li>通过随机生成的salt和密码明文（或者MD5等方法）加密后存入数据库</li>
<li>在controller中通过before_filter来阻止未通过认证的用户对action进行调用</li>
<li>在view中通过如islogin?，isadmin?等方法来让保护需要登录或者为管理员的行为</li>
</ul>
<p>插件中一般都是做出一个Model和两个Controller，处理用户数据的User。而Controller，一个负责登录和登出，另一个User的负责用户创建和删除。</p>
<p>关于记住用户状态的实现，大部分用户认证的插件都有。参考<a href="http://codingbitch.com/p/comboy/User+authentication+in+Ruby+on+Rails">User+authentication+in+Ruby+on+Rails</a>：<br />
添加一个cookie_hash字段到user中：<br />
<code>class AddUserCookieHash &lt; ActiveRecord::Migration<br />
&nbsp;def self.up<br />
&nbsp;&nbsp;add_column :users, :cookie_hash, :string<br />
&nbsp;end<br />
&nbsp;def self.down<br />
&nbsp;&nbsp;remove_column :users, :cookie_hash<br />
&nbsp;end<br />
end</code><br />
接着在登录页面，如login.html.erb中，加入：<br />
<code> remember me</code><br />
然后在管理login的controller中添加：<br />
<code>def login<br />
&nbsp;if request.post?<br />
&nbsp;&nbsp;@user = User.find_by_username(params[:login])<br />
&nbsp;&nbsp;if @user and @user.password_is? params[:password]<br />
&nbsp;&nbsp;&nbsp;session[:uid] = @user.id<br />
&nbsp;&nbsp;&nbsp;# 当用户需要被记住时，开始对cookie进行处理<br />
&nbsp;&nbsp;&nbsp;# 对cookie生成一个密钥之后放入cookie和存入数据库（user表中）<br />
&nbsp;&nbsp;&nbsp;# 其中还指定了一个cookies失效时间，默认为30天，其实可以把这个参数提出来<br />
&nbsp;&nbsp;&nbsp;if params[:remember]<br />
&nbsp;&nbsp;&nbsp;&nbsp;cookie_pass = [Array.new(9){rand(256).chr}.join].pack("m").chomp<br />
&nbsp;&nbsp;&nbsp;&nbsp;cookie_hash = Digest::MD5.hexdigest(cookie_pass + &nbsp;&nbsp;&nbsp;&nbsp;@user.password_salt)<br />
&nbsp;&nbsp;&nbsp;&nbsp;cookies[:userapp_login_pass] = { :value =&gt; cookie_pass, :expires =&gt; 30.days.from_now }<br />
&nbsp;&nbsp;&nbsp;&nbsp;cookies[:userapp_login] = { :value =&gt; @user.username, :expires =&gt; 30.days.from_now }<br />
&nbsp;&nbsp;&nbsp;&nbsp;User.update(@user.id, :cookie_hash =&gt; cookie_hash)<br />
&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;redirect_to :controller =&gt; 'panel', :action =&gt; 'secret'<br />
&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;@auth_error = 'Bad username or password'<br />
&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
&nbsp;end</code><br />
最后在ApplicationController中加入：<br />
<code>session :session_key =&gt; '_userapp_session_id'<br />
before_filter :check_cookie<br />
def check_cookie<br />
  return if session[:uid]<br />
  if cookies[:logowanie_login]<br />
    @user = User.find_by_username(cookies[:userapp_login])<br />
    return unless @user<br />
    cookie_hash = Digest::MD5.hexdigest(cookies[:userapp_login_pass] + @user.password_salt)<br />
    if @user.cookie_hash == cookie_hash<br />
      flash[:info] = 'You\'ve been automatically logged in' # annoying msg<br />
      session[:uid] = @user.id<br />
    else<br />
      flash[:error] = 'Something is wrong with your cookie'<br />
    end<br />
  end<br />
end</code><br />
而关于角色的认证可以使用插件：<a href="http://active-rbac.rubyforge.org/">ActiveRBAC </a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/28/rails%ef%bc%8c%e7%94%a8%e6%88%b7%e8%ae%a4%e8%af%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>改了一下CSS</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/26/%e6%94%b9%e4%ba%86%e4%b8%80%e4%b8%8bcss/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/26/%e6%94%b9%e4%ba%86%e4%b8%80%e4%b8%8bcss/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 15:02:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[something]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/26/%e6%94%b9%e4%ba%86%e4%b8%80%e4%b8%8bcss/</guid>
		<description><![CDATA[昨晚看了一下CSS基础教程，中午突发奇想改了一下这里的CSS，改为流式布局。改了一下标题，本来想整块标题区域改的，结果发现上面有一块黑色的东西，怎么整也整不掉，算了，就改一下标题颜色就好了。还有改了一下字体，字间距，链接的颜色。
CSS其实不难理解，但是实际操作和设计上，就要依靠个人的艺术嗅觉和想像力了，看来我没有这方面的天赋。
说说blog的问题，这里的二级域名失效了，要去问问sky怎么了。想去找其它的blog系统，wordpress.com提供的wordpress没有加上代码高亮系统， google提供的blogger国内访问不到它的二级域名，又不喜欢javaeye的blog，也不想回到以前的blogjava那个系统（感觉自己的 blog会淹没在那一堆抄书帖和转帖中）。最好的还是自己去租个空间，用个Mephisto或者typo 系统，这样还可以练习自己配置和管理Rails应用的能力。
]]></description>
			<content:encoded><![CDATA[<p>昨晚看了一下CSS基础教程，中午突发奇想改了一下<a href="http://rc.org.cn/?1352">这里</a>的CSS，改为流式布局。<span id="more-18"></span>改了一下标题，本来想整块标题区域改的，结果发现上面有一块黑色的东西，怎么整也整不掉，算了，就改一下标题颜色就好了。还有改了一下字体，字间距，链接的颜色。</p>
<p>CSS其实不难理解，但是实际操作和设计上，就要依靠个人的艺术嗅觉和想像力了，看来我没有这方面的天赋。</p>
<p>说说blog的问题，这里的二级域名失效了，要去问问sky怎么了。想去找其它的blog系统，wordpress.com提供的wordpress没有加上代码高亮系统， google提供的blogger国内访问不到它的二级域名，又不喜欢javaeye的blog，也不想回到以前的blogjava那个系统（感觉自己的 blog会淹没在那一堆抄书帖和转帖中）。最好的还是自己去租个空间，用个<a href="http://mephistoblog.com/">Mephisto</a>或者<a href="http://www.typosphere.org/">typo</a> 系统，这样还可以练习自己配置和管理Rails应用的能力。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/26/%e6%94%b9%e4%ba%86%e4%b8%80%e4%b8%8bcss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby1.9的变化（一） &#8211; 新的语法和语意</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/25/ruby19%e7%9a%84%e5%8f%98%e5%8c%96%ef%bc%88%e4%b8%80%ef%bc%89-%e6%96%b0%e7%9a%84%e8%af%ad%e6%b3%95%e5%92%8c%e8%af%ad%e6%84%8f/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/25/ruby19%e7%9a%84%e5%8f%98%e5%8c%96%ef%bc%88%e4%b8%80%ef%bc%89-%e6%96%b0%e7%9a%84%e8%af%ad%e6%b3%95%e5%92%8c%e8%af%ad%e6%84%8f/#comments</comments>
		<pubDate>Fri, 25 Jan 2008 01:07:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/25/ruby19%e7%9a%84%e5%8f%98%e5%8c%96%ef%bc%88%e4%b8%80%ef%bc%89-%e6%96%b0%e7%9a%84%e8%af%ad%e6%b3%95%e5%92%8c%e8%af%ad%e6%84%8f/</guid>
		<description><![CDATA[资料来自：http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9
 文中有实验性标记的说明很可能会在短时间内被拿掉，原文中解释为”crazy ideas“。 最近将持续连载翻译Ruby1.9的变化。
 新的语法和语意
 新的字面量hash语法[Ruby2]
{a: "foo"}&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; # =&#62; {:a=&#62;"foo"}
代码块局部变量 [实验性]
 如下使用:
# {normal args一般参数; 局部变量local variables}
 d = 2
 a = lambda{&#124;;d&#124; d = 1}
 a.call()
 d&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; # =&#62; 2
当一个变量被隐藏时，Ruby1.9会给出一个警告:
-:2: warning: shadowing outer local variable - d
代码块参数的作用域总是在代码块内
a = 1
 10.times{&#124;a&#124; } [...]]]></description>
			<content:encoded><![CDATA[<p>资料来自：<a href="http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9">http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9</a></p>
<p> 文中有实验性标记的说明很可能会在短时间内被拿掉，原文中解释为”crazy ideas“。<br /> 最近将持续连载翻译Ruby1.9的变化。<span id="more-19"></span></p>
<p> <font size="5">新的语法和语意</font></p>
<p> <font size="4">新的字面量hash语法[Ruby2]</font><br />
<code>{a: "foo"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # =&gt; {:a=&gt;"foo"}</code><br />
<font size="4">代码块局部变量 [实验性]</font></p>
<p> 如下使用:<br />
<code># {normal args一般参数; 局部变量local variables}<br />
 d = 2<br />
 a = lambda{|;d| d = 1}<br />
 a.call()<br />
 d&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # =&gt; 2</code><br />
当一个变量被隐藏时，Ruby1.9会给出一个警告:<br />
<code>-:2: warning: shadowing outer local variable - d</code><br />
<font size="4">代码块参数的作用域总是在代码块内</font><br />
<code>a = 1<br />
 10.times{|a| } # !&gt; shadowing outer local variable - a 代码块外的局部变量a被隐藏<br />
  a&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # =&gt; 1</code><br />
<font size="4"> 新的lambdas语法 [非常实验性]</font><br />
<code> a = -&gt;(b,c){ b + c }<br /> a.call(1,2) # =&gt; 3</code><br />
注意这里没有说是替换目前传统的代码块语法。Matz已经明确说明了后者会永远有效。新的语法允许为代码块参数指定默认值，如<code> {|a,b=1| ... } </code>这种语法在目前的基于bison的Ruby解析器LALR是不能实现的.</p>
<p> 这种新语法可以不用括号包裹参数:<br />
<code> -&gt; { }.call # =&gt; nil<br />
-&gt; a, b&nbsp;&nbsp;{ a + b }.call(1,2) # =&gt; 3<br />
c = 1; -&gt; a, b; c&nbsp;&nbsp;{ c = a + b }.call(1,2); c # =&gt; 1</code><br />
还可以更加诡异地使用:<br />
<code> c = 2; -&gt; ;c { c = 1 }.call; c # =&gt; 2</code><br />
甚至是<br />
<code> c = 2; -&gt; *d ; c { d }.call(1,2,3) # =&gt; [1, 2, 3]<br />
c = 2; -&gt; ; c { c = 1 }.call; c # =&gt; 2</code><br />
<font size="4"> 用.()替代使用call方法或者[]方法来调用Procs[实验性]</font></p>
<p> 现在可以这样做:<br />
<code>a = lambda{|*b| b}<br />
a.(1,2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # =&gt; [1, 2]</code><br />
注意你需要句点:<br />
<code>a = lambda{|*b| b}<br />
a(1,2)&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;#&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;(eval):2: syntax error...<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;#&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; (a)(1,2)...<br />
~&gt; -:2: undefined method `a' for main:Object (NoMethodError)</code><br />
<font size="4">可以在括号内使用任何表达式:</font><code>(lambda{|a,b| a + b}).(1,2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # =&gt; 3</code><font size="4"><br /> .()用法会无视接受者而调用其call方法:</font><br />
<code> "foo".(1,2)&nbsp; &nbsp;# ~&gt;&nbsp;&nbsp;undefined method `call' for "foo":String (NoMethodError)</code><br />
<font size="4">Block arguments代码块参数</font></p>
<p> 代码块可以使用&amp;block参数:<br />
<code>define_method(:foo){|&amp;b| b.call(bar)}</code><br />
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/23533"><b>ruby-dev:23533</b></a></p>
<p> <font size="4">新的代码块参数语意</font></p>
<p> |v|现在会像|v,|的形式工作:<br />
<code>[RUBY_VERSION, RUBY_RELEASE_DATE]&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; ["1.8.5", "2006-08-25"]<br />
 def m; yield 1, 2; end<br />
m{|v| v}&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt; [1, 2] # !&gt; multiple values for a block parameter (2 for 1)</code><br />
相对应的：<br />
<code>[RUBY_VERSION, RUBY_RELEASE_DATE]&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; ["1.9.0", "2007-08-03"]<br />
def m; yield 1, 2; end<br />
m{|v| v}&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt; 1</code><br />
<font size="4">to_splat 方法使用*参数</font><br /> 用to_splat方法代替to_a方法</p>
<p> nil.to_splat 返回 [].</p>
<p> <font size="4">允许多个*操作符</font></p>
<p> 经Audrey Tang建议，Ruby1.9允许在方法调用是使用多个*操作符<br />
<code>&nbsp; &nbsp;def foo(*a)<br /> &nbsp; &nbsp;&nbsp;&nbsp;a<br />
&nbsp; &nbsp;end<br /> &nbsp; &nbsp;<br />
&nbsp; &nbsp;foo(1, *[2,3], 4, *[5,6])&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt; [1, 2, 3, 4, 5, 6]</code><br />
表达式也是：<br />
<code> [RUBY_VERSION, RUBY_RELEASE_DATE]&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # =&gt; ["1.9.0", "2007-08-03"]<br />
a = [1,2,3]<br />
b = [4,5,6]<br />
[*a, *b]&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; [1, 2, 3, 4, 5, 6]</code><br />
<font size="4">允许在可选参数后加上必要参数</font></p>
<p> <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/29014"><b>ruby-dev:29014</b></a><br />
<code>&nbsp; &nbsp;def m(a, b=nil, *c, d)<br />
&nbsp; &nbsp;&nbsp;&nbsp;[a,b,c,d]<br /> &nbsp; &nbsp;end<br />
&nbsp; &nbsp;m(1,2)&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; [1, nil, [], 2]</code><br />
<font size="4">?c的语意</font></p>
<p> ?a现在返回一个单字符字符串代替原来的整数值:<code> ?a&nbsp; &nbsp;# =&gt; "a"</code><br />
<font size="4">[] 方法的参数</font></p>
<p> 可以在[]方法中使用星号，&#8221;assocs&#8221;(不用方括号的hash)和代码块参数:<br />
<code>&nbsp; &nbsp;RUBY_VERSION&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt; "1.9.0"<br />
&nbsp; &nbsp;RUBY_RELEASE_DATE&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # =&gt; "2006-06-11"<br />
&nbsp; &nbsp;class Foo; def [](*a, &amp;block); block.call(a) end end<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;a = (0..3).to_a<br />
&nbsp; &nbsp;Foo.new[*a, :op =&gt; :+]{|x| x }&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt; [0, 1, 2, 3, {:op=&gt;:+}]</code><br />
<font size="4">printf风格的格式化字符串(%)</font><br /> %c 可以输出单字符字符串<br /> %u 为负数提供类似%d的格式<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/11575"> (ruby-core:11575)</a></p>
<p> <font size="4">允许三元运算符( ? : )扩展到新行</font><br />
<code> p 1 == 2 ?<br />
&nbsp; &nbsp;0<br />
&nbsp; &nbsp;:<br />
&nbsp; &nbsp;1<br />
# &gt;&gt; 1</code><br />
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/29189">ruby-dev:29189</a></p>
<p> <font size="4"> defined?方法和局部变量</font><br />
<code>RUBY_VERSION&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; "1.8.5"<br />
RUBY_RELEASE_DATE&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt; "2006-08-25"<br />
a = 0<br />
defined? a&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # =&gt; "local-variable"<br />
1.times do |i|<br />
&nbsp;&nbsp;defined? i&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; "local-variable(in-block)"<br />
end</code><br />
相对应的：<br />
<code>RUBY_VERSION&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; "1.9.0"<br />
RUBY_RELEASE_DATE&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;# =&gt; "2007-08-03"<br />
a = 0<br />
defined? a&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # =&gt; "local-variable"<br />
1.times do |i|<br />
&nbsp;&nbsp;defined? i&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;# =&gt; "local-variable"<br />
end</code></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/25/ruby19%e7%9a%84%e5%8f%98%e5%8c%96%ef%bc%88%e4%b8%80%ef%bc%89-%e6%96%b0%e7%9a%84%e8%af%ad%e6%b3%95%e5%92%8c%e8%af%ad%e6%84%8f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10分钟在NetBeans6上创建Rails2.0的weblog</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/23/10%e5%88%86%e9%92%9f%e5%9c%a8netbeans6%e4%b8%8a%e5%88%9b%e5%bb%barails20%e7%9a%84weblog-2/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/23/10%e5%88%86%e9%92%9f%e5%9c%a8netbeans6%e4%b8%8a%e5%88%9b%e5%bb%barails20%e7%9a%84weblog-2/#comments</comments>
		<pubDate>Tue, 22 Jan 2008 18:25:24 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/23/10%e5%88%86%e9%92%9f%e5%9c%a8netbeans6%e4%b8%8a%e5%88%9b%e5%bb%barails20%e7%9a%84weblog-2/</guid>
		<description><![CDATA[原文来自：http://blogs.sun.com/divas/entry/creating_a_rails_2_0
 本文是之前NetBean6关于Ruby部分的教程（http://www.ruby-lang.org.cn/forums/thread-1896-1-1.html）其中的一个例子，如何在10分钟创建一个Weblog的升级版。我会把和之前的不同之处用蓝色标记出来
 Rails2.0到来之后带来了很多新的特性，新的变化，这样就导致了以前大量的Rails1.2.X的示例无法在升级到Rails2.0之后运行。 NetBeans6关于Ruby部分的教程中的例子就是这样，由于之前采用的是Rails1.2.5还有ActionController的脚手架方法（scaffold），这些与Rails 2.0并不兼容，故作者写了一篇文章，也就是之前那篇的升级版，一边学习Rails 2.0的新特性新变化，一边修改例子。
 首先创建一个Rails项目，这个和以前一样，也就是File &#62; New Project，名字取weblog2.0吧，具体参考上面提到的那篇旧的文章！
 创建出项目后自动打开database.yml，真是神奇，NB6竟然帮我们修改好了，使用了以前默认的MySQL，莫非它知道我们对MySQL比较熟？配置一下用户名和密码吧。然后就右键点击项目选择Rake Task =&#62; db =&#62; create来创建数据库。
 接着开始使用Rails 2.0的脚手架创建Model和Controller。右击项目后选择Generate，接着在下拉列表中选择scaffold，再在Model栏中输入Post title:string。注意在Rails 2.0下不能在此对话框的Controller和Action栏里填入字符。这样就创建好了Post model和PostsController还有相关的view（可以看到后缀都改为.html.erb了）。在生成的迁移任务（migrate）中可以看到Rails 2.0的新脚手架已经帮你填好了，如下代码：
# db/migrate/001_create_posts.rb
class CreatePosts &#60; ActiveRecord::Migration
 &#160;&#160;def self.up &#160; &#160; create_table :posts do &#124;t&#124;
 &#160; &#160;&#160; &#160;t.string :title &#160; &#160;&#160; &#160;t.timestamps
 &#160; &#160; end
 &#160;&#160;end
 &#160;&#160;def self.down
&#160; &#160; drop_table :posts
 &#160;&#160;end
end
那就直接可以运行migrate了，和之前一样，右击项目=&#62; Migrate Database =&#62; To [...]]]></description>
			<content:encoded><![CDATA[<p>原文来自：<a href="http://blogs.sun.com/divas/entry/creating_a_rails_2_0">http://blogs.sun.com/divas/entry/creating_a_rails_2_0</a></p>
<p> 本文是之前NetBean6关于Ruby部分的教程（<a href="http://www.ruby-lang.org.cn/forums/thread-1896-1-1.html">http://www.ruby-lang.org.cn/forums/thread-1896-1-1.html</a>）其中的一个例子，如何在10分钟创建一个Weblog的升级版。<span id="more-37"></span>我会把和之前的不同之处用<font color="Blue">蓝色</font>标记出来</p>
<p> Rails2.0到来之后带来了很多新的特性，新的变化，这样就导致了以前大量的Rails1.2.X的示例无法在升级到Rails2.0之后运行。 NetBeans6关于Ruby部分的教程中的例子就是这样，由于之前采用的是Rails1.2.5还有ActionController的脚手架方法（scaffold），这些与Rails 2.0并不兼容，故作者写了一篇文章，也就是之前那篇的升级版，一边学习Rails 2.0的新特性新变化，一边修改例子。</p>
<p> 首先创建一个Rails项目，这个和以前一样，也就是File &gt; New Project，名字取weblog2.0吧，具体参考上面提到的那篇旧的文章！</p>
<p> 创建出项目后自动打开database.yml，真是神奇，NB6竟然帮我们修改好了，使用了以前默认的MySQL，莫非它知道我们对MySQL比较熟？配置一下用户名和密码吧。然后就<font color="Blue">右键点击项目选择Rake Task =&gt; db =&gt; create</font>来创建数据库。</p>
<p> 接着开始使用Rails 2.0的脚手架创建Model和Controller。右击项目后选择Generate，<font color="Blue">接着在下拉列表中选择scaffold，再在Model栏中输入Post title:string。注意在Rails 2.0下不能在此对话框的Controller和Action栏里填入字符。</font>这样就创建好了Post model和PostsController还有<font color="Blue">相关的view（可以看到后缀都改为.html.erb了）</font>。在生成的迁移任务（migrate）中可以看到Rails 2.0的新脚手架已经帮你填好了，如下代码：<br />
<code># db/migrate/001_create_posts.rb<br />
class CreatePosts &lt; ActiveRecord::Migration<br />
 &nbsp;&nbsp;def self.up<br /> &nbsp; &nbsp; create_table :posts do |t|<br />
 &nbsp; &nbsp;&nbsp; &nbsp;t.string :title<br /> &nbsp; &nbsp;&nbsp; &nbsp;t.timestamps<br />
 &nbsp; &nbsp; end<br />
 &nbsp;&nbsp;end<br />
 &nbsp;&nbsp;def self.down<br />
&nbsp; &nbsp; drop_table :posts<br />
 &nbsp;&nbsp;end<br />
end</code><br />
那就直接可以运行migrate了，和之前一样，右击项目=&gt; Migrate Database =&gt; To current version，或者 Rake Task =&gt; db =&gt; migrate。<br /> 接下来就可以运行一下看看这个应用了。不过先要修改默认路由，注释掉默认路由（welcome），然后添加新的路由:<br />
<code># config/routes.rb<br /> # map.root :controller =&gt; "welcome"<br />
 map.root :controller =&gt; "posts"</code><br />
Rails 2.0脚手架默认生成的规则是REST的，以后添加自定义的Controller的Action要用REST化的方式编写路由。这里可以看到用的也是 <font color="Blue">具名路由，map.root</font>。接着删除了public/ index.html后按下NB6工具栏上面大大的三角形运行服务器，这就可以用浏览器打开那localhost:3000看到我们刚刚完成的一切了。 </p>
<p> 按照之前的教程里，下一步就是添加Post的字段。右击Database Magrate =&gt; Generate，接着在Argument栏中填入AddBodyToPost body:text。这样Rails 2.0又帮我们写好了migrate任务，剩下的就是执行migrate任务。添加了新的字段后，就要修改view了，让我们再次打开Generate对话框，在下拉框中选择scaffold，在Model栏输入Post title:string body:text &#8211;skip-migration，并且这次要在下面的单选按钮中选择overwrite。然后就可以打开浏览器看看生效了没有。</p>
<p> 下一步就是让Rails对创建Post时进行输入校验。这里展示的是对Post的属性进行非空校验，在Post Model源码（ap<br /> p/model/post.rb）中新建一行，输入vp再按tab，NB6的模板完成功能就体现了，vp自动扩展为 validates_presence_of，那接着就输入:title, :body。（由此可得vu就是 validates_uniqueness_of，试了一下，果然，具体模板完成请看NB6中选项里关于模板的部分）下来就是打开浏览器试验一下。 </p>
<p> 最后一步就是稍微打扮一下weblog，打开app/view/posts/index.html.erb，把文件里的内容替换为以下内容：<br />
<code>&lt;h1&gt;The Ruby Blog&lt;/h1&gt;<br />
 &lt;% @posts.each do |post| %&gt;<br />
&nbsp;&nbsp;&lt;h2&gt;&lt;%= post.title %&gt;&lt;/h2&gt;<br />
&nbsp;&nbsp;&lt;p&gt;&lt;%= post.body %&gt;&lt;/p&gt;<br />
&nbsp;&nbsp;&lt;small&gt; &lt;%= link_to 'Permalink', post_path(post) %&gt;&lt;/small&gt;<br />
&nbsp;&nbsp;&lt;hr&gt;<br />
&lt;% end %&gt;<br />
&lt;br /&gt;<br />
 &lt;%= link_to 'New post', new_post_path %&gt;</code><br />
最后就是让Posts按时间顺序显示，把上面第3行代码改为：<br />
<code>&lt;% @posts.reverse.each do |post| %&gt;</code><br />
可以看到在视图中，<font color="Blue">新的脚手架创建的这句代码&lt;%= link_to &#8216;New post&#8217;, new_post_path %&gt;中的new_post_path</font>，这是Rails2.0中REST化的体现之一。另外，原文中第6行代码还是以前那种写法，也就是指定controller和action的写法，我改了过来，让它和下面New Post的写法统一，我在原文下面留言提了这个。</p>
<p> 很多同学都有问我，Rails升级到2.0后NB6中关于Ruby的这个10分钟创建weblog的教程怎么做，这里就是答案。有什么错误请大家指出来哦。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/23/10%e5%88%86%e9%92%9f%e5%9c%a8netbeans6%e4%b8%8a%e5%88%9b%e5%bb%barails20%e7%9a%84weblog-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>寒假开始了。。。</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e5%bc%80%e5%a7%8b%e4%ba%86%e3%80%82%e3%80%82%e3%80%82/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e5%bc%80%e5%a7%8b%e4%ba%86%e3%80%82%e3%80%82%e3%80%82/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 10:41:22 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[假期]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e5%bc%80%e5%a7%8b%e4%ba%86%e3%80%82%e3%80%82%e3%80%82/</guid>
		<description><![CDATA[2008年的寒假，一回到家就感冒了。。。有点郁闷，明明学校比家冷那么多我都没有感冒，怎么一回家就感冒了。
另外对家里电脑的龟速真是。。。，内存不足是一回事，P4真的不如超了频的A3000+，而且宽带对比学校的校园网也是逊色很多。。。不能一边开bt和电驴，一边编译一些东西，再一边听歌。有时gvim还会卡一卡，rails的rake任务也是很慢。。。期待暑假买的HP6510b。。。
回到家里觉得少了安全感，回来那天上楼时发现一家人给入室盗窃了，又听说几个月前对面那栋楼也给入室了。
小区里的大树都给锯了，整个小区有种和以前不同的感觉，凄凉的感觉。。。
寒假开始了，又有一堆时间要自己支配，自己学习。要实现自己在一个月前定下的计划。
给自己加油！
]]></description>
			<content:encoded><![CDATA[<p>2008年的寒假，一回到家就感冒了。。。有点郁闷，明明学校比家冷那么多我都没有感冒，怎么一回家就感冒了。<span id="more-44"></span><br />
另外对家里电脑的龟速真是。。。，内存不足是一回事，P4真的不如超了频的A3000+，而且宽带对比学校的校园网也是逊色很多。。。不能一边开bt和电驴，一边编译一些东西，再一边听歌。有时gvim还会卡一卡，rails的rake任务也是很慢。。。期待暑假买的HP6510b。。。</p>
<p>回到家里觉得少了安全感，回来那天上楼时发现一家人给入室盗窃了，又听说几个月前对面那栋楼也给入室了。</p>
<p>小区里的大树都给锯了，整个小区有种和以前不同的感觉，凄凉的感觉。。。</p>
<p>寒假开始了，又有一堆时间要自己支配，自己学习。要实现自己在一个月前定下的计划。</p>
<p>给自己加油！</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e5%bc%80%e5%a7%8b%e4%ba%86%e3%80%82%e3%80%82%e3%80%82/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>寒假书单</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e4%b9%a6%e5%8d%95/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e4%b9%a6%e5%8d%95/#comments</comments>
		<pubDate>Sun, 20 Jan 2008 19:26:42 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[假期]]></category>
		<category><![CDATA[读书]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e4%b9%a6%e5%8d%95/</guid>
		<description><![CDATA[这是寒假的看书计划
励志类：
《高效能人士的七个习惯》《要事第一》，科维的两本修身的书。
技术类：
《RESTful Web Services》，深入认识REST，这本书的大部分例子都是用rails写的。DHH作序推荐的。
《JavaScript高级程序设计》，是时候看看JS了，不懂JS的话，做Web开发是有点辛苦。
还有把《Rails Cookbook》的笔记整理出来。
]]></description>
			<content:encoded><![CDATA[<p>这是寒假的看书计划</p>
<p>励志类：<br />
《高效能人士的七个习惯》《要事第一》，科维的两本修身的书。</p>
<p>技术类：<br />
《RESTful Web Services》，深入认识REST，这本书的大部分例子都是用rails写的。DHH作序推荐的。</p>
<p>《JavaScript高级程序设计》，是时候看看JS了，不懂JS的话，做Web开发是有点辛苦。</p>
<p>还有把《Rails Cookbook》的笔记整理出来。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/21/%e5%af%92%e5%81%87%e4%b9%a6%e5%8d%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>thin简介</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/10/thin%e7%ae%80%e4%bb%8b/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/10/thin%e7%ae%80%e4%bb%8b/#comments</comments>
		<pubDate>Thu, 10 Jan 2008 12:13:47 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/01/10/thin%e7%ae%80%e4%bb%8b/</guid>
		<description><![CDATA[
 官方主页：http://code.macournoyer.com/thin/
 thin是个合成品，分别使用了来自mongrel的解析器，Every Machine的网络IO库，Rack的web服务器和Ruby框架的接口。
 也就是说thin有mongrel的速度和安全性，有Every Machine的高伸缩性，性能和稳定性。
 
 那如何在你的Rails中使用thin呢？
 首先安装thin：
gem install thin
然后要运行thin服务器就在你的根目录下执行：
thin start
运行成功：
&#62;&#62; Thin web server (v0.5.0)
&#62;&#62; Listening on 0.0.0.0:3000, CTRL+C to stop
另外一个运行thin的方法（通过Rack的rackup命令）： 在你的Rails应用根目录下创建一个名为config.ru的文件：
require 'rubygems'
require 'thin'
app = proc do &#124;env&#124;
 &#160;&#160;[ 200, { 'Content-Type' =&#62; 'text/html' }, ['hi'] ]
end
run app
然后就执行
rackup -s thin
这样也可以运行thin服务器。
 本文相关资料： http://code.macournoyer.com/thin/ http://mongrel.rubyforge.org/ http://rubyeventmachine.com/ http://rack.rubyforge.org/
 另： Rack支持的服务器： 
 
&#160; &#160; Mongrel 
&#160; &#160; Mongrel/Swiftcore [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://code.macournoyer.com/thin/images/logo.gif"/></p>
<p> 官方主页：<a href="http://code.macournoyer.com/thin/">http://code.macournoyer.com/thin/</a></p>
<p> thin是个合成品，分别使用了来自mongrel的解析器，Every Machine的网络IO库，Rack的web服务器和Ruby框架的接口。<span id="more-36"></span></p>
<p> 也就是说thin有mongrel的速度和安全性，有Every Machine的高伸缩性，性能和稳定性。</p>
<p> <img src="http://chart.apis.google.com/chart?cht=bvg&amp;chd=t:14.98,54.8723076923077,48.9184615384615,79.9276923076923%7C14.8692307692308,65.0615384615385,70.4446153846154,89.5553846153846%7C14.9476923076923,35.1123076923077,70.18,88.6769230769231&amp;chbh=16&amp;chs=350x150&amp;chl=WEBrick%7CMongrel%7CEvented%20M.%7CThin&amp;chco=000000,666666,cccccc&amp;chdl=1%20c%20req.%7C10%20c%20req.%7C100%20c%20req."/></p>
<p> 那如何在你的Rails中使用thin呢？</p>
<p> 首先安装thin：<br />
<code>gem install thin</code><br />
然后要运行thin服务器就在你的根目录下执行：<br />
<code>thin start</code><br />
运行成功：<br />
<code>&gt;&gt; Thin web server (v0.5.0)<br />
&gt;&gt; Listening on 0.0.0.0:3000, CTRL+C to stop</code><br />
另外一个运行thin的方法（通过Rack的rackup命令）：<br /> 在你的Rails应用根目录下创建一个名为config.ru的文件：<br />
<code>require 'rubygems'<br />
require 'thin'<br />
app = proc do |env|<br />
 &nbsp;&nbsp;[ 200, { 'Content-Type' =&gt; 'text/html' }, ['hi'] ]<br />
end<br />
run app</code><br />
然后就执行<br />
<code>rackup -s thin</code><br />
这样也可以运行thin服务器。</p>
<p> 本文相关资料：<br /> <a href="http://code.macournoyer.com/thin/">http://code.macournoyer.com/thin/</a><br /> <a href="http://mongrel.rubyforge.org/">http://mongrel.rubyforge.org/</a><br /> <a href="http://rubyeventmachine.com/">http://rubyeventmachine.com/</a><br /> <a href="http://rack.rubyforge.org/">http://rack.rubyforge.org/</a></p>
<p> 另：<br /> Rack支持的服务器：<br /> 
<ul> 
<li>&nbsp; &nbsp; Mongrel </li>
<li>&nbsp; &nbsp; Mongrel/Swiftcore </li>
<li>&nbsp; &nbsp; WEBrick </li>
<li>&nbsp; &nbsp; FCGI </li>
<li>&nbsp; &nbsp; CGI </li>
</ul>
<p>对岸的同学的讨论：<br />
http://lightyror.thegiive.net/2008/01/thin-mongrel-app-server.html</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/10/thin%e7%ae%80%e4%bb%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails2.0的官方plugins列表&#8211;从1.2中分离出来的一些功能</title>
		<link>http://redworld.blog.ubuntu.org.cn/2008/01/09/rails20%e7%9a%84%e5%ae%98%e6%96%b9plugins%e5%88%97%e8%a1%a8-%e4%bb%8e12%e4%b8%ad%e5%88%86%e7%a6%bb%e5%87%ba%e6%9d%a5%e7%9a%84%e4%b8%80%e4%ba%9b%e5%8a%9f%e8%83%bd/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2008/01/09/rails20%e7%9a%84%e5%ae%98%e6%96%b9plugins%e5%88%97%e8%a1%a8-%e4%bb%8e12%e4%b8%ad%e5%88%86%e7%a6%bb%e5%87%ba%e6%9d%a5%e7%9a%84%e4%b8%80%e4%ba%9b%e5%8a%9f%e8%83%bd/#comments</comments>
		<pubDate>Wed, 09 Jan 2008 02:09:23 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/01/09/rails20%e7%9a%84%e5%ae%98%e6%96%b9plugins%e5%88%97%e8%a1%a8-%e4%bb%8e12%e4%b8%ad%e5%88%86%e7%a6%bb%e5%87%ba%e6%9d%a5%e7%9a%84%e4%b8%80%e4%ba%9b%e5%8a%9f%e8%83%bd/</guid>
		<description><![CDATA[Rails2.0中把Rails1.2中的一些功能分离出来作为插件。最近论坛上就有很多人问关于Rails2.0怎么缺失了一些功能的问题，这里就是答案，以后看到什么功能不见了，看看这贴就OK了。比如acts_as_list，scaffolding，还有一些Ajax的辅助方法等。
 下载地址：http://svn.rubyonrails.org/rails/plugins/
 列表 
 
account_location/ 
acts_as_list/ 
acts_as_nested_set/ 
acts_as_tree/ 
atom_feed_helper/ 
auto_complete/ 
continuous_builder/ 
deadlock_retry/ 
exception_notification/ 
http_authentication/ 
in_place_editing/ 
javascript_test/ 
legacy/ 
localization/ 
open_id_authentication/ 
scaffolding/ 
scriptaculous_slider/ 
ssl_requirement/ 
token_generator/ 
tzinfo_timezone/ 
tztime/ 
upload_progress/ 

]]></description>
			<content:encoded><![CDATA[<p>Rails2.0中把Rails1.2中的一些功能分离出来作为插件。<span id="more-35"></span>最近论坛上就有很多人问关于Rails2.0怎么缺失了一些功能的问题，这里就是答案，以后看到什么功能不见了，看看这贴就OK了。比如acts_as_list，scaffolding，还有一些Ajax的辅助方法等。</p>
<p> 下载地址：<a href="http://svn.rubyonrails.org/rails/plugins/">http://svn.rubyonrails.org/rails/plugins/</a></p>
<p> 列表<br /> 
<ul> 
<li>account_location/ </li>
<li>acts_as_list/ </li>
<li>acts_as_nested_set/ </li>
<li>acts_as_tree/ </li>
<li>atom_feed_helper/ </li>
<li>auto_complete/ </li>
<li>continuous_builder/ </li>
<li>deadlock_retry/ </li>
<li>exception_notification/ </li>
<li>http_authentication/ </li>
<li>in_place_editing/ </li>
<li>javascript_test/ </li>
<li>legacy/ </li>
<li>localization/ </li>
<li>open_id_authentication/ </li>
<li>scaffolding/ </li>
<li>scriptaculous_slider/ </li>
<li>ssl_requirement/ </li>
<li>token_generator/ </li>
<li>tzinfo_timezone/ </li>
<li>tztime/ </li>
<li>upload_progress/ </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2008/01/09/rails20%e7%9a%84%e5%ae%98%e6%96%b9plugins%e5%88%97%e8%a1%a8-%e4%bb%8e12%e4%b8%ad%e5%88%86%e7%a6%bb%e5%87%ba%e6%9d%a5%e7%9a%84%e4%b8%80%e4%ba%9b%e5%8a%9f%e8%83%bd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DMD在Ubuntu下的安装配置</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/12/31/dmd%e5%9c%a8ubuntu%e4%b8%8b%e7%9a%84%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%ae/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/12/31/dmd%e5%9c%a8ubuntu%e4%b8%8b%e7%9a%84%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%ae/#comments</comments>
		<pubDate>Sun, 30 Dec 2007 19:04:21 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[D Language]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[D语言]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/12/31/dmd%e5%9c%a8ubuntu%e4%b8%8b%e7%9a%84%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%ae/</guid>
		<description><![CDATA[D语言是下一个主流静态语言霸主的强有力候选人。DMD是D语言的一个编译器。
到下面的地址下载dmd，后解压。（其中dmd/src/dmd是dmd的源码，dmd/sample/d是d语言的几个简单示例。）http://www.digitalmars.com/d/dcompiler.html

安装配置文件，复制dmd/bin/dmd.conf到 /usr/local/bin下。
 为dmd/bin下的这几个文件添加执行权限，dmd,dumpobj,obj2asm,rdmd。 
安装编译器，复制上面的几个文件到 /usr/local/bin。
 安装lib，复制dmd/lib/libphobos2.a 到 /usr/local/lib。
 安装源码，复制dmd/src/phobos到/usr/local/src。
安装man，复制dmd/man/man1下的所有文件到/usr/local/man/man1下。

这样就OK了。
 dmd.conf也可以放在/etc下不过要把lib和src的路径改为绝对路径，原文件中的路径是用%@P%来标示当前路径。
测试一下编译，没有报找不到文件就OK了。
其实D语言也是红色的。。。D语言应该是接任 Java和C#的下个静态语言王者。现在几个主流的编辑器都支持D语言，比如vim，emacs，scite。
 dmd中带的几个例子中有几个是只能在windows下运行的，有点不爽。
D语言的几个资源：http://www.digitalmars.com/d/index.htmlhttp://www.dnaic.com/d/doc/d/index.htmlhttp://www.dsource.org
]]></description>
			<content:encoded><![CDATA[<p>D语言是下一个主流静态语言霸主的强有力候选人。DMD是D语言的一个编译器。<span id="more-34"></span><br />
到下面的地址下载dmd，后解压。（其中dmd/src/dmd是dmd的源码，dmd/sample/d是d语言的几个简单示例。）<br />http://www.digitalmars.com/d/dcompiler.html
<ol>
<li><font size="2">安装配置文件，复制<tt>dmd/bin/dmd.conf</tt>到 <tt>/usr/local/bin下</tt>。</font></li>
<li> <font size="2">为dmd/bin下的这几个文件添加执行权限，dmd,dumpobj,obj2asm,rdmd。</font> </li>
<li><font size="2">安装编译器，复制上面的几个文件到 <tt>/usr/local/bin。</tt></font></li>
<li> <font size="2">安装lib，复制dmd/lib/libphobos2.a 到 <tt>/usr/local/lib</tt>。</font></li>
<li> <font size="2">安装源码，复制dmd/src/phobos到/usr/local/src。</font></li>
<li><font size="2">安装man，复制dmd/man/man1下的所有文件到/usr/local/man/man1下。</font></li>
</ol>
<p>这样就OK了。</p>
<p> dmd.conf也可以放在/etc下不过要把lib和src的路径改为绝对路径，原文件中的路径是用%@P%来标示当前路径。</p>
<p>测试一下编译，没有报找不到文件就OK了。</p>
<p>其实D语言也是红色的。。。D语言应该是接任 Java和C#的下个静态语言王者。现在几个主流的编辑器都支持D语言，比如vim，emacs，scite。</p>
<p> dmd中带的几个例子中有几个是只能在windows下运行的，有点不爽。</p>
<p>D语言的几个资源：<br />http://www.digitalmars.com/d/index.html<br />http://www.dnaic.com/d/doc/d/index.html<br />http://www.dsource.org</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/12/31/dmd%e5%9c%a8ubuntu%e4%b8%8b%e7%9a%84%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%ae/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Typo的汉化</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/12/30/typo%e7%9a%84%e6%b1%89%e5%8c%96/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/12/30/typo%e7%9a%84%e6%b1%89%e5%8c%96/#comments</comments>
		<pubDate>Sun, 30 Dec 2007 07:38:42 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/12/30/typo%e7%9a%84%e6%b1%89%e5%8c%96/</guid>
		<description><![CDATA[昨天在本机搭建了一个Blog，本来想搭wiki的，但是觉得用ruby写的不好用，比如instiki。相对于其它语言写的wiki （Wikipedia，moin等），现在用Ruby写的wiki还是不够成熟。
下载Typo 后解压。

在lang目录下新建一个zh_CN.rb文件，然后仿照 lang中的其它文件进行翻译。
在ApplicationController类中添加这行：&#38; nbsp; Localization.lang = &#8216;zh_CN&#8217;。

这样就OK了。
我用 de_DE.rb来汉化，汉化了70%左右，算是个半成品，还没有怎么校对过。
]]></description>
			<content:encoded><![CDATA[<p>昨天在本机搭建了一个Blog，本来想搭wiki的，但是觉得用ruby写的不好用，比如instiki。相对于其它语言写的wiki （Wikipedia，moin等），现在用Ruby写的wiki还是不够成熟。</p>
<p>下载Typo 后解压。</p>
<ol>
<li>在lang目录下新建一个zh_CN.rb文件，然后仿照 lang中的其它文件进行翻译。</li>
<li>在ApplicationController类中添加这行：&amp; nbsp; Localization.lang = &#8216;zh_CN&#8217;。</li>
</ol>
<p>这样就OK了。</p>
<p>我用 de_DE.rb来汉化，汉化了70%左右，算是个半成品，还没有怎么校对过。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/12/30/typo%e7%9a%84%e6%b1%89%e5%8c%96/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>康抽西</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/11/29/%e5%ba%b7%e6%8a%bd%e8%a5%bf/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/11/29/%e5%ba%b7%e6%8a%bd%e8%a5%bf/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 19:03:11 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[大学]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/11/29/%e5%ba%b7%e6%8a%bd%e8%a5%bf/</guid>
		<description><![CDATA[今天上《操作系统》课时，老师忽然大放厥词：
“其实你们不要把Linux看的那么神秘，和windows是一样的。它有一个X-Windows图形界面。。。微软的windows有世界上最好的界面。。。Linux是什么F什么G的软件，都是免费的，开放源代码的，所以界面很难看。。。商业软件才是最好的。。。我们实验室用的红帽子就是一个Linux系统，你们看了之后就知道界面很难看，和现在用的windows没法比的。。。Linux就是不好。。。gcc是个很强大编译软件，也是免费的。它和一般的编译器不一样，在windows下要进行编译链接，gcc直接就输出二进制文件，不用链接，很先进。。。为什么要用Linux做系统调用的实验而不用windows呢？因为Linux是用C写的，可以用函数调用的形式进行系统调用的。”
对于上面的言论，我想每个Linux Fan都会听到很不爽，包括我。不是不爽windows和Linux比较，是不爽她的无知。其实又提界面的这个常见的口水战主题的话，讲太多也是没意义的。只是她不是那同个时代的东西来比较，根本没有可比性，RedHat Linux 9同时间段的微软windows产品是windows 2000（或者NT），界面一比校，色盲都看得出哪个好看。到了现在的“畏死它”和同时期的装上了Bery和Compiz的Ubuntu，这次无论在性能上还是在美观上，还是Linux领先，而且不止领先一个身位。每次她都是提到X-window都是叫做“X-windows”，我前两次都是说出来纠正一下，她基本不理会我的意见，后来基本我习惯了，觉得算了。基本上看国外的视频教程，他们都是用Mac OSX或者Linux的，我上次也在一篇文章里说过，一个不经常用Linux外国佬他竟然懂得很多很多Linux的知识。对于外国的学术和教育机构不用 windows的说法我也听说了很多次。为什么中国会这样呢？
这门课的老师是个副教授，还是西电大毕业的研究生。都快50（或者过50）的人了，知识面还那么小，感觉她很多时候都是在误导人。有时不是我喜欢逃课，是去那里听课，听到老师一些讲错的地方实在会让我很难受。我总觉得一个从事计算机相关行业的人，对技术应该体会很深，至少对某个方面应该是很熟的，可是我发现很多老师都没有。有一次某老师在说：“我很喜欢研究编程语言，我懂得很多种语言，比如C啊，C++，Java，Pacal，还有你们应该没有听说的elisp，那是一种编辑器的扩展语言，还有Fortran我也会。其实编程语言都是一样的，差不多的。”我觉得说编程语言都一样的人，一般都不会是个很厉害的人。以后写篇日志讲讲这个。
看到这里看这篇文章的人会问，题目为什么叫“康抽西”？因为这位老师讲到Linux怎么中断程序时，说Ctrl+C的时候就念“康抽西”。
]]></description>
			<content:encoded><![CDATA[<p>今天上《操作系统》课时，老师忽然大放厥词：<span id="more-33"></span><br />
“其实你们不要把Linux看的那么神秘，和windows是一样的。它有一个X-Windows图形界面。。。微软的windows有世界上最好的界面。。。Linux是什么F什么G的软件，都是免费的，开放源代码的，所以界面很难看。。。商业软件才是最好的。。。我们实验室用的红帽子就是一个Linux系统，你们看了之后就知道界面很难看，和现在用的windows没法比的。。。Linux就是不好。。。gcc是个很强大编译软件，也是免费的。它和一般的编译器不一样，在windows下要进行编译链接，gcc直接就输出二进制文件，不用链接，很先进。。。为什么要用Linux做系统调用的实验而不用windows呢？因为Linux是用C写的，可以用函数调用的形式进行系统调用的。”</p>
<p>对于上面的言论，我想每个Linux Fan都会听到很不爽，包括我。不是不爽windows和Linux比较，是不爽她的无知。其实又提界面的这个常见的口水战主题的话，讲太多也是没意义的。只是她不是那同个时代的东西来比较，根本没有可比性，RedHat Linux 9同时间段的微软windows产品是windows 2000（或者NT），界面一比校，色盲都看得出哪个好看。到了现在的“畏死它”和同时期的装上了Bery和Compiz的Ubuntu，这次无论在性能上还是在美观上，还是Linux领先，而且不止领先一个身位。每次她都是提到X-window都是叫做“X-windows”，我前两次都是说出来纠正一下，她基本不理会我的意见，后来基本我习惯了，觉得算了。基本上看国外的视频教程，他们都是用Mac OSX或者Linux的，我上次也在一篇文章里说过，一个不经常用Linux外国佬他竟然懂得很多很多Linux的知识。对于外国的学术和教育机构不用 windows的说法我也听说了很多次。为什么中国会这样呢？</p>
<p>这门课的老师是个副教授，还是西电大毕业的研究生。都快50（或者过50）的人了，知识面还那么小，感觉她很多时候都是在误导人。有时不是我喜欢逃课，是去那里听课，听到老师一些讲错的地方实在会让我很难受。我总觉得一个从事计算机相关行业的人，对技术应该体会很深，至少对某个方面应该是很熟的，可是我发现很多老师都没有。有一次某老师在说：“我很喜欢研究编程语言，我懂得很多种语言，比如C啊，C++，Java，Pacal，还有你们应该没有听说的elisp，那是一种编辑器的扩展语言，还有Fortran我也会。其实编程语言都是一样的，差不多的。”我觉得说编程语言都一样的人，一般都不会是个很厉害的人。以后写篇日志讲讲这个。</p>
<p>看到这里看这篇文章的人会问，题目为什么叫“康抽西”？因为这位老师讲到Linux怎么中断程序时，说Ctrl+C的时候就念“康抽西”。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/11/29/%e5%ba%b7%e6%8a%bd%e8%a5%bf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SVN简单图文教程</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/11/25/svn%e7%ae%80%e5%8d%95%e5%9b%be%e6%96%87%e6%95%99%e7%a8%8b/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/11/25/svn%e7%ae%80%e5%8d%95%e5%9b%be%e6%96%87%e6%95%99%e7%a8%8b/#comments</comments>
		<pubDate>Sat, 24 Nov 2007 19:02:03 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/11/25/svn%e7%ae%80%e5%8d%95%e5%9b%be%e6%96%87%e6%95%99%e7%a8%8b/</guid>
		<description><![CDATA[这个教程主要面向还对svn操作一窍不通的同学。下面的操作环境是Linux下的，windows下安装svn后也可。 
 首先checkout出来。 命令语法为 svn co URL dir（会提示输入用户名和密码）URL为svn仓库地址，dir为本地文件夹（即存放checkout出来文件的本地文件夹）
Screenshot-chenk@chen: ~-tmp.png
 checkout出来的目录：
Screenshot-repo &#8211; 文件管理器.png
 然后添加文件进去。（先把要上传的文件复制到对应的文件夹里，然后再执行命令）
Screenshot-branches &#8211; 文件管理器.png
 执行添加命令： 命令语法为svn add uploadfile
Screenshot-chenk@chen: ~-tmp-repo.png
 最后执行commit完成提交。 命令语法为svn ci -m &#8220;提交信息&#8221;
Screenshot-chenk@chen: ~-tmp-repo-1.png
 以后每次更新到最新的版本只要在仓库目录下执行svn update就可以了。
Screenshot-chenk@chen: ~-cn_repo.png
 checkout和commit可以简写为co和ci。
 要查看版本信息可以执行svn log：
Screenshot-chenk@chen: ~-cn_repo.png
 一般我们在中文化工作中要做的就是这些了。
]]></description>
			<content:encoded><![CDATA[<p>这个教程主要面向还对svn操作一窍不通的同学。下面的操作环境是Linux下的，windows下安装svn后也可。<span id="more-32"></span> </p>
<p> 首先checkout出来。<br /> 命令语法为 svn co URL dir（会提示输入用户名和密码）URL为svn仓库地址，dir为本地文件夹（即存放checkout出来文件的本地文件夹）</p>
<p><a href="http://ruby-lang.org.cn/forums/attachment.php?aid=464"><img src="http://ruby-lang.org.cn/forums/attachments/month_0711/20071125_817fe63770c09c7496baqJS86tK9lP7D.png" border="0"/><br />Screenshot-chenk@chen: ~-tmp.png</a></p>
<p> checkout出来的目录：</p>
<p><a href="http://ruby-lang.org.cn/forums/attachment.php?aid=465"><img src="http://ruby-lang.org.cn/forums/attachments/month_0711/20071125_925985de2dd2ec071c33yhDjSepAs4Ws.png" border="0"/><br />Screenshot-repo &#8211; 文件管理器.png</a></p>
<p> 然后添加文件进去。（先把要上传的文件复制到对应的文件夹里，然后再执行命令）</p>
<p><a href="http://ruby-lang.org.cn/forums/attachment.php?aid=466"><img src="http://ruby-lang.org.cn/forums/attachments/month_0711/20071125_c1ea7e282031c8a6cc7f2mBHS6AHkQZp.png" border="0"/><br />Screenshot-branches &#8211; 文件管理器.png</a></p>
<p> 执行添加命令：<br /> 命令语法为svn add uploadfile</p>
<p><a href="http://ruby-lang.org.cn/forums/attachment.php?aid=467"><img src="http://ruby-lang.org.cn/forums/attachments/month_0711/20071125_0596670cf0ccf24cce47C6iZvrQtc2RT.png" border="0"/><br />Screenshot-chenk@chen: ~-tmp-repo.png</a></p>
<p> 最后执行commit完成提交。<br /> 命令语法为svn ci -m &#8220;提交信息&#8221;</p>
<p><a href="http://ruby-lang.org.cn/forums/attachment.php?aid=468"><img src="http://ruby-lang.org.cn/forums/attachments/month_0711/20071125_1f9f05ff7a64243d0d50aHqQyEqDxbeX.png" border="0"/><br />Screenshot-chenk@chen: ~-tmp-repo-1.png</a></p>
<p> 以后每次更新到最新的版本只要在仓库目录下执行svn update就可以了。</p>
<p><a href="http://ruby-lang.org.cn/forums/attachment.php?aid=469"><img src="http://ruby-lang.org.cn/forums/attachments/month_0711/20071125_7b9d574c6314db336ef4hXhQEZSXpiIV.png" border="0"/><br />Screenshot-chenk@chen: ~-cn_repo.png</a></p>
<p> checkout和commit可以简写为co和ci。</p>
<p> 要查看版本信息可以执行svn log：</p>
<p><a href="http://ruby-lang.org.cn/forums/attachment.php?aid=470"><img src="http://ruby-lang.org.cn/forums/attachments/month_0711/20071125_26f4c9d92faf81c41d2arJmNwJTtIsBt.png" border="0"/><br />Screenshot-chenk@chen: ~-cn_repo.png</a></p>
<p> 一般我们在中文化工作中要做的就是这些了。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/11/25/svn%e7%ae%80%e5%8d%95%e5%9b%be%e6%96%87%e6%95%99%e7%a8%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NetBeans文档中文化工作总结</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/11/24/netbeans%e6%96%87%e6%a1%a3%e4%b8%ad%e6%96%87%e5%8c%96%e5%b7%a5%e4%bd%9c%e6%80%bb%e7%bb%93/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/11/24/netbeans%e6%96%87%e6%a1%a3%e4%b8%ad%e6%96%87%e5%8c%96%e5%b7%a5%e4%bd%9c%e6%80%bb%e7%bb%93/#comments</comments>
		<pubDate>Sat, 24 Nov 2007 01:42:18 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/11/24/netbeans%e6%96%87%e6%a1%a3%e4%b8%ad%e6%96%87%e5%8c%96%e5%b7%a5%e4%bd%9c%e6%80%bb%e7%bb%93/</guid>
		<description><![CDATA[NetBeans6的Ruby文档是我们团队第一次的任务。这个活动也是我发起的，我要承担的不止是翻译方面的任务，还有协调管理上的任务。
 在组织管理上的总结： 

在管理上不够正规。这主要和我的管理经验不足有关，在学生会里学到的一点点管理经验根本不够。
没有能把大家积极性完全调动起来，导致大家讨论不积极。
任务的时间控制不好，提交校对时间没有分配好。从第三次任务开始我会定时发邮件通知每个人距离要提交还有多少时间，还有跟进好每个人的情况。
对每次翻译任务的分析不到位，每次都是到了翻译完了才能找出一些前期分析不足。这个以后要下点功夫分析翻译的任务，这对翻译的工作将是很好的前期准备，对提高翻译效率和质量有很大帮助。
校对任务的分配不到位。以后要重视校对任务的分配还有完成的问题。
由于有两处讨论区（google论坛和这里），导致讨论内容分散。以后规定google论坛只负责分配任务和一些通知，讨论集中在论坛。

 在翻译上： 

英文基础不好，很多惯用短语搭配不懂意思。这个我正在看英语短语和搭配。
对句型，对介词把握不好。这个还是要靠翻译多一点文章。

在翻译上其实随着翻译的，看的文章多了水平有在慢慢提高着。现在还没有完成的NetBeans6的第二期任务，问题主要是校对上的，校对的速度跟不上，这个我会好好分析一下怎么解决。其实在这个活动中drive2me大哥的帮助和支持是至关重要的，如果没有他的帮忙我真的是搞不起这个活动。不过到目前为止，我还不能做到让大哥满意的工作，无论在管理上还是翻译上，我除了抱歉之外，能做的就是在下次任务中我做得更好。

]]></description>
			<content:encoded><![CDATA[<p>NetBeans6的Ruby文档是我们团队第一次的任务。<span id="more-45"></span>这个活动也是我发起的，我要承担的不止是翻译方面的任务，还有协调管理上的任务。</p>
<p> 在组织管理上的总结：<br /> 
<ul>
<li>在管理上不够正规。这主要和我的管理经验不足有关，在学生会里学到的一点点管理经验根本不够。</li>
<li>没有能把大家积极性完全调动起来，导致大家讨论不积极。</li>
<li>任务的时间控制不好，提交校对时间没有分配好。从第三次任务开始我会定时发邮件通知每个人距离要提交还有多少时间，还有跟进好每个人的情况。</li>
<li>对每次翻译任务的分析不到位，每次都是到了翻译完了才能找出一些前期分析不足。这个以后要下点功夫分析翻译的任务，这对翻译的工作将是很好的前期准备，对提高翻译效率和质量有很大帮助。</li>
<li>校对任务的分配不到位。以后要重视校对任务的分配还有完成的问题。</li>
<li>由于有两处讨论区（google论坛和这里），导致讨论内容分散。以后规定google论坛只负责分配任务和一些通知，讨论集中在论坛。</li>
</ul>
<p> 在翻译上：<br /> 
<ul>
<li>英文基础不好，很多惯用短语搭配不懂意思。这个我正在看英语短语和搭配。</li>
<li>对句型，对介词把握不好。这个还是要靠翻译多一点文章。</li>
</ul>
<p>在翻译上其实随着翻译的，看的文章多了水平有在慢慢提高着。现在还没有完成的NetBeans6的第二期任务，问题主要是校对上的，校对的速度跟不上，这个我会好好分析一下怎么解决。其实在这个活动中drive2me大哥的帮助和支持是至关重要的，如果没有他的帮忙我真的是搞不起这个活动。不过到目前为止，我还不能做到让大哥满意的工作，无论在管理上还是翻译上，我除了抱歉之外，能做的就是在下次任务中我做得更好。
<div></div>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/11/24/netbeans%e6%96%87%e6%a1%a3%e4%b8%ad%e6%96%87%e5%8c%96%e5%b7%a5%e4%bd%9c%e6%80%bb%e7%bb%93/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sinatra：一个优雅地包装了Web开发的DSL</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/11/12/sinatra%ef%bc%9a%e4%b8%80%e4%b8%aa%e4%bc%98%e9%9b%85%e5%9c%b0%e5%8c%85%e8%a3%85%e4%ba%86web%e5%bc%80%e5%8f%91%e7%9a%84dsl/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/11/12/sinatra%ef%bc%9a%e4%b8%80%e4%b8%aa%e4%bc%98%e9%9b%85%e5%9c%b0%e5%8c%85%e8%a3%85%e4%ba%86web%e5%bc%80%e5%8f%91%e7%9a%84dsl/#comments</comments>
		<pubDate>Sun, 11 Nov 2007 18:54:34 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/11/12/sinatra%ef%bc%9a%e4%b8%80%e4%b8%aa%e4%bc%98%e9%9b%85%e5%9c%b0%e5%8c%85%e8%a3%85%e4%ba%86web%e5%bc%80%e5%8f%91%e7%9a%84dsl/</guid>
		<description><![CDATA[你相信用100行代码可以实现一个博客吗？用Sinatra框架就可以做到。下面就是这样子的一个Web应用：
 Reprise &#8211; A Minimalistic Blog  这个应用的代码：点这里查看
 一个简单的hello world的web应用要写多少代码？用Sinatra只需5行代码：
CODE:
require 'rubygems' require 'sinatra'
 get '/' do &#160;&#160;'Hello World' endSinatra官方主页：http://sinatra.rubyforge.org/
]]></description>
			<content:encoded><![CDATA[<p>你相信用100行代码可以实现一个博客吗？用Sinatra框架就可以做到。<span id="more-31"></span>下面就是这样子的一个Web应用：</p>
<p> <font size="4"><a href="http://journal.redflavor.com/reprise---a-minimalistic-blog">Reprise &#8211; A Minimalistic Blog</a><br /> </font><br /> 这个应用的代码：点<a href="http://redflavor.com/reprise.rb">这里</a>查看</p>
<p> 一个简单的hello world的web应用要写多少代码？用Sinatra只需5行代码：
<p>CODE:</p>
<p><code>require 'rubygems'<br /> require 'sinatra'</p>
<p> get '/' do<br /> &nbsp;&nbsp;'Hello World'<br /> end</code>Sinatra官方主页：<a href="http://sinatra.rubyforge.org/">http://sinatra.rubyforge.org/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/11/12/sinatra%ef%bc%9a%e4%b8%80%e4%b8%aa%e4%bc%98%e9%9b%85%e5%9c%b0%e5%8c%85%e8%a3%85%e4%ba%86web%e5%bc%80%e5%8f%91%e7%9a%84dsl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NetBeans IDE 6.0 Ruby 译文</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/11/07/netbeans-ide-60-ruby-%e8%af%91%e6%96%87/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/11/07/netbeans-ide-60-ruby-%e8%af%91%e6%96%87/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 18:51:22 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/11/07/netbeans-ide-60-ruby-%e8%af%91%e6%96%87/</guid>
		<description><![CDATA[NetBeans IDE 6.0 Ruby 文档 
原文标题：NetBeans IDE 6.0 Ruby Documentation 原文作者：Sun 原文地址：http://www.netbeans.org/kb/60/ruby/index.html
 译者：Ruby中文社区翻译团队 译文首发：http://ruby-lang.org.cn/forums/thread-1896-1-1.html
 转载请保留本版权信息，违者必究！
 下面题目为中文的文章为完成翻译的文章，而视频演示为官网提供的Flash。
 10月 2007
 教程和演示
 配置环境Ruby环境

Installing and Configuring Ruby Support

 使用Ruby编辑器

Editing Ruby Code [视频演示]
代码补全视频演示
代码提示和快速修正视频演示

 集成Java和Ruby开发  

Mixing Java and Ruby Applications [视频演示]

 介绍 Ruby on Rails

10分钟内创建一个RubyWeb日志 [视频演示]
创建Rails模型类间的关系
与Ruby on Rails一起使用Ajax

 使用Ruby on Rails做更多的事


Flickr在Rails中的应用[视频演示]

Using jMaki With NetBeans Ruby[视频演示]

 调试和测试&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p><font color="#ff8c00"></font><font size="6"></font><font color="#ff0000">NetBeans IDE 6.0 Ruby 文档<br /> <span id="more-30"></span></font><br />
<blockquote><font color="#ff0000">原文标题：</font><font face="Times New Roman, serif"></font><font color="#ff0000"></font><font size="3">NetBeans IDE 6.0 Ruby Documentation</font><font color="#ff0000"><br /> 原文作者：</font>Sun<br /> <font color="#ff0000">原文地址：<a href="http://www.netbeans.org/kb/60/ruby/index.html"><u>http://www.netbeans.org/kb/60/ruby/index.html</u></a></font></p>
<p> <font color="#ff0000">译者：Ruby中文社区翻译团队</font><br /> <font color="#ff0000">译文首发：<a href="http://ruby-lang.org.cn/forums/thread-1896-1-1.html"><u>http://ruby-lang.org.cn/forums/thread-1896-1-1.html</u></a></font></p>
<p> <font color="#ff0000">转载请保留本版权信息，违者必究！</font></p></blockquote>
<p><font size="3"><br /> 下面题目为中文的文章为完成翻译的文章，而视频演示为官网提供的Flash。</font></p>
<p> 10月 2007</p>
<p> <font size="5"></font><font color="#ff8c00">教程和演示</font></p>
<p> <font size="4"></font><font color="#ff8c00">配置环境Ruby环境</font>
<ul>
<li><a href="http://www.netbeans.org/kb/60/ruby/setting-up.html">Installing and Configuring Ruby Support</a></li>
</ul>
<p> <font color="#ff8c00"></font><font size="4">使用Ruby编辑器</font>
<ul>
<li><a href="http://www.netbeans.org/kb/60/ruby/editing.html">Editing Ruby Code</a> <font color="#0000ff">[</font><a href="http://www.netbeans.org/download/flash/jruby_editing/jruby_editing.html"><u>视频演示</u></a><font color="#0000ff">]</font></li>
<li><a href="http://netbeans.tv/technologies/Tor-Norbye-uses-NetBeans-Ruby-Editor-Code-Completion-169/"><u>代码补全视频演示</u></a></li>
<li><a href="http://netbeans.tv/technologies/Tor-Norbye-uses-hints-and-quick-fixes-in-NetBeans-Ruby-Editor-170/">代码提示和快速修正视频演示</a></li>
</ul>
<p> <font size="4"></font><font color="#ff8c00">集成Java和Ruby开发 </font><br /> 
<ul>
<li><a href="http://www.netbeans.org/kb/60/ruby/java-ruby.html">Mixing Java and Ruby Applications</a> [<a href="http://www.netbeans.tv/interviews/Tor-Norbye-mixes-Ruby-and-Java-development-using-NetBeans-151/">视频演示</a>]</li>
</ul>
<p> <font size="4"></font><font color="#ff8c00">介绍 Ruby on Rails</font>
<ul>
<li><a href="http://ruby-lang.org.cn/forums/viewthread.php?tid=1896&amp;page=1&amp;extra=page%3D1#pid7321">10分钟内创建一个RubyWeb日志</a> [<a href="http://www.netbeans.org/download/flash/jruby_on_rails/jruby_on_rails.html">视频演示</a>]</li>
<li><a href="http://ruby-lang.org.cn/forums/viewthread.php?tid=1896&amp;;page=1&amp;extra=page%3D1#pid7328">创建Rails模型类间的关系</a></li>
<li><a href="http://ruby-lang.org.cn/forums/viewthread.php?tid=1896&amp;;page=1&amp;extra=page%3D1#pid7331">与Ruby on Rails一起使用Ajax</a></li>
</ul>
<p> <font size="4"></font><font color="#ff8c00">使用Ruby on Rails做更多的事</font>
<ul>
<li>
<p align="left"><font color="black"><a href="http://ruby-lang.org.cn/forums/viewthread.php?tid=1896&amp;page=1&amp;extra=page%3D1#pid7332">Flickr在Rails中的应用</a>[<a href="http://www.netbeans.org/kb/55/flickr-on-rails-flash.html">视频演示</a>]</font></p>
</li>
<li><a href="http://blogs.sun.com/divas/entry/using_jmaki_1_0_with">Using jMaki With NetBeans Ruby</a>[<a href="http://blogs.sun.com/arungupta/entry/screencast_web8_jmaki_on_rails">视频演示</a>]</li>
</ul>
<p> <font size="4"></font><font color="#ff8c00">调试和测试&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;</font><font size="4">&nbsp; &nbsp; </font>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
<ul>
<li><a href="http://www.netbeans.tv/technologies/Roman-Strobl-Demonstrates-the-NetBeans-Ruby-Debugger-193/">调试Ruby代码视频演示</a></li>
<li><a href="http://www.netbeans.org/kb/60/ruby/unittest.html">Test-Driven Rails Development</a></li>
</ul>
<div></div>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/11/07/netbeans-ide-60-ruby-%e8%af%91%e6%96%87/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>出局出局</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/30/%e5%87%ba%e5%b1%80%e5%87%ba%e5%b1%80/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/30/%e5%87%ba%e5%b1%80%e5%87%ba%e5%b1%80/#comments</comments>
		<pubDate>Mon, 29 Oct 2007 20:44:25 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[大学]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/30/%e5%87%ba%e5%b1%80%e5%87%ba%e5%b1%80/</guid>
		<description><![CDATA[今天打联赛的8强赛 ，被淘汰了
今天一开场我这边就进了一个，但是很快禁区里手球送了一个点球让他们追平了，后来就给人又进多两个。本来在领先后还有三个机会，一个中柱，两个给对方后卫补了空门。
这是第二次的联赛，也是倒数第二次。大一没有经验打的很烂，大二又没有举行，到现在大三了感觉有机会夺冠了，可以又止步于8强，到了大四的时候体力上应该是跟不上了。反正很失望。
今天我基本上拿不到球，控不到球，传出的威胁球不多，太失败。本来想着天天去练球，结果练到今天还没比赛整条腿就已经很酸痛了。都怪昨天去当裁判，弄完之后看见别人在踢球又去踢了一下，想走的时候看见别人跑步的时候又去跑了几圈。欲速则不达，早知道不要练什么体力了，保留体力好好打比赛更好，今年联赛都没有进球。后悔阿。。
不过这次的联赛里，我班里的人都表现的很团结，我就是喜欢足球的这种团结的气氛。下个星期再和一班来一场友谊赛。联赛没得打了之后时间就比较多了，不用经常去训练，不用经常很累要休息很多，刚好rubyist要开始了可以专心的开发还有做好我的翻译。
联赛出局，心情郁闷中&#8230;&#8230;
]]></description>
			<content:encoded><![CDATA[<p>今天打联赛的8强赛 ，被淘汰了<span id="more-46"></span></p>
<p>今天一开场我这边就进了一个，但是很快禁区里手球送了一个点球让他们追平了，后来就给人又进多两个。本来在领先后还有三个机会，一个中柱，两个给对方后卫补了空门。</p>
<p>这是第二次的联赛，也是倒数第二次。大一没有经验打的很烂，大二又没有举行，到现在大三了感觉有机会夺冠了，可以又止步于8强，到了大四的时候体力上应该是跟不上了。反正很失望。</p>
<p>今天我基本上拿不到球，控不到球，传出的威胁球不多，太失败。本来想着天天去练球，结果练到今天还没比赛整条腿就已经很酸痛了。都怪昨天去当裁判，弄完之后看见别人在踢球又去踢了一下，想走的时候看见别人跑步的时候又去跑了几圈。欲速则不达，早知道不要练什么体力了，保留体力好好打比赛更好，今年联赛都没有进球。后悔阿。。</p>
<p>不过这次的联赛里，我班里的人都表现的很团结，我就是喜欢足球的这种团结的气氛。下个星期再和一班来一场友谊赛。联赛没得打了之后时间就比较多了，不用经常去训练，不用经常很累要休息很多，刚好rubyist要开始了可以专心的开发还有做好我的翻译。</p>
<p>联赛出局，心情郁闷中&#8230;&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/30/%e5%87%ba%e5%b1%80%e5%87%ba%e5%b1%80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>翻译好难</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91%e5%a5%bd%e9%9a%be/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91%e5%a5%bd%e9%9a%be/#comments</comments>
		<pubDate>Sun, 28 Oct 2007 14:46:15 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91%e5%a5%bd%e9%9a%be/</guid>
		<description><![CDATA[昨天翻译了drive2me推荐的一篇文章作为翻译练习。今天在drive2me大哥（大叔）的耐心指导下完成了修改和校对。

看懂一篇英文的文章不难，把它翻译出来就难了。信达雅自己说的多，也上过china-pub骂过一些译者不负责任翻译得不好（再次谴责一下TDD中译本的译者），到自己翻译的时候就知道翻译是什么滋味了。
由于我的英语基础不好，对于比较口语化的英语，英语的分词，时态，还有介词都处理得不好，遇到它们时我就有点不知所措了：（
drive2me 大哥在指导中，教会了我翻译的几个要点。翻译要注意细节，细节决定成败。英文文章和中文一样，整个文章都是围绕着一个中心，每一句都是和其上下文紧紧相关的，开始觉得之前高中到小学的语文课教的对文章的分析有用了，比如这个词在这里意义不明显，但是结合全文来看这个词的含义就出来了。还有对于句式的处理，比如转折，比较等等，在英文中一两个词就可以表达出来，中文可能要花好几个词还有语气来表达。最后还有一点，要忠于原文，忠于作者原意，作者表达出来的就翻译出来，作者没有说的就不要多加上去。最后这点看上去好像很废话，可是到了真正在翻译时就能理解了。
嗯嗯，就是经验，这对我以后很有帮助。我相信我以后的翻译更好的。组织文档翻译小组是一次机会，一次让我提高的机会，我想我能做好的。
]]></description>
			<content:encoded><![CDATA[<p>昨天翻译了drive2me推荐的一篇文章作为翻译练习。今天在drive2me大哥（大叔）的耐心指导下完成了修改和校对。<br />
<span id="more-27"></span><br />
看懂一篇英文的文章不难，把它翻译出来就难了。信达雅自己说的多，也上过china-pub骂过一些译者不负责任翻译得不好（再次谴责一下TDD中译本的译者），到自己翻译的时候就知道翻译是什么滋味了。</p>
<p>由于我的英语基础不好，对于比较口语化的英语，英语的分词，时态，还有介词都处理得不好，遇到它们时我就有点不知所措了：（</p>
<p>drive2me 大哥在指导中，教会了我翻译的几个要点。翻译要注意细节，细节决定成败。英文文章和中文一样，整个文章都是围绕着一个中心，每一句都是和其上下文紧紧相关的，开始觉得之前高中到小学的语文课教的对文章的分析有用了，比如这个词在这里意义不明显，但是结合全文来看这个词的含义就出来了。还有对于句式的处理，比如转折，比较等等，在英文中一两个词就可以表达出来，中文可能要花好几个词还有语气来表达。最后还有一点，要忠于原文，忠于作者原意，作者表达出来的就翻译出来，作者没有说的就不要多加上去。最后这点看上去好像很废话，可是到了真正在翻译时就能理解了。</p>
<p>嗯嗯，就是经验，这对我以后很有帮助。我相信我以后的翻译更好的。组织文档翻译小组是一次机会，一次让我提高的机会，我想我能做好的。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91%e5%a5%bd%e9%9a%be/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]Rails 2.0 features: Multiple views</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91rails-20-features-multiple-views/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91rails-20-features-multiple-views/#comments</comments>
		<pubDate>Sat, 27 Oct 2007 18:49:37 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91rails-20-features-multiple-views/</guid>
		<description><![CDATA[Rails 2.0特性：复合视图
标签: framework, ruby, Ruby on Rails
作者： madpilot
本文由Ruby中文化团队的Maninred翻译，转载请注明出处，谢谢合作。&#60; br&#62;
原文链接：
http://www.sitepoint.com/blogs/2 &#8230; res-multiple-views/
下一个主要版本的Ruby on Rails（指2.0）加入了复合视图这个新特性。大约上个月底，预览版发布了，我有幸试用了一下，我想及时地概述一下一些新特点。
复合视图
在rails 1.2中，支持多种数据类型的respond_to块被引入，它可以轻松地支持象XML或者JSON。你需要做就是像下面这样：
CODE:
def index
@stories = Story.find :all
respond to { &#124;format&#124;
format.html {}
format.xml {
render :xml =&#62; @stories.to_xml
}
format.json {
render :json =&#62; @stories.to_json
}
}
end然后在浏览器上，如果你加上了扩展文件（比如/stories/index.xml）并得到包括请求格式的内容，那么你可以在environment.rb文件的最后添加MIME::Type.register，来创建自定义的类型。
这种做法的一个问题是，基于扩展文件这种方式没有办法支持不同的HTML页面。因为MIME::Type解析器工作方式是，添加其他MIME类型为 text/html的内容标识（handler）会扰乱默认的标识（handler），这意味着上面的代码会提供错误的视图。
输入Mime::Type.register_alias
现在你可以告诉Rails用HTML响应你希望使用的多种文件类型。就是说你想设计一个mobile版本和iPhone版本的站点，你能通过添加下面的代码到/config/initializers/mime_types.rb文件创建两个新的格式：
CODE:
Mime::Type.register_alias "text/html", :iphone
Mime::Type.register_alias "text/html", :mobile这使下面代码可以运作:
CODE:
def index
@stories = Story.find :all
respond to { &#124;format&#124;
format.html {}
format.xml {
render :xml =&#62; @stories.to_xml
}
format.json {
render :json =&#62; @stories.to_json
}
format.iphone {
// Serve up the [...]]]></description>
			<content:encoded><![CDATA[<p><strong><font SIZE="5">Rails 2.0特性：复合视图</font></strong></p>
<p>标签: framework, ruby, Ruby on Rails</p>
<p>作者： madpilot</p>
<p><font COLOR="#0000ff">本文由Ruby中文化团队的Maninred翻译，转载请注明出处，谢谢合作。</font><span id="more-29"></span>&lt; br&gt;<br />
原文链接：<br />
<a HREF="http://www.sitepoint.com/blogs/2007/10/26/rails-20-features-multiple-views/">http://www.sitepoint.com/blogs/2 &#8230; res-multiple-views/</a></p>
<p>下一个主要版本的Ruby on Rails（指2.0）加入了复合视图这个新特性。大约上个月底，预览版发布了，我有幸试用了一下，我想及时地概述一下一些新特点。</p>
<p><strong><font SIZE="4">复合视图</font></strong></p>
<p>在rails 1.2中，支持多种数据类型的respond_to块被引入，它可以轻松地支持象XML或者JSON。你需要做就是像下面这样：</p>
<p>CODE:</p>
<p><code>def index<br />
@stories = Story.find :all<br />
respond to { |format|<br />
format.html {}<br />
format.xml {<br />
render :xml =&gt; @stories.to_xml<br />
}<br />
format.json {<br />
render :json =&gt; @stories.to_json<br />
}<br />
}<br />
end</code>然后在浏览器上，如果你加上了扩展文件（比如/stories/index.xml）并得到包括请求格式的内容，那么你可以在environment.rb文件的最后添加MIME::Type.register，来创建自定义的类型。</p>
<p>这种做法的一个问题是，基于扩展文件这种方式没有办法支持不同的HTML页面。因为MIME::Type解析器工作方式是，添加其他MIME类型为 text/html的内容标识（handler）会扰乱默认的标识（handler），这意味着上面的代码会提供错误的视图。</p>
<p><strong><font SIZE="4">输入Mime::Type.register_alias</font></strong></p>
<p>现在你可以告诉Rails用HTML响应你希望使用的多种文件类型。就是说你想设计一个mobile版本和iPhone版本的站点，你能通过添加下面的代码到/config/initializers/mime_types.rb文件创建两个新的格式：</p>
<p>CODE:</p>
<p><code>Mime::Type.register_alias "text/html", :iphone<br />
Mime::Type.register_alias "text/html", :mobile</code>这使下面代码可以运作:</p>
<p>CODE:</p>
<p><code>def index<br />
@stories = Story.find :all<br />
respond to { |format|<br />
format.html {}<br />
format.xml {<br />
render :xml =&gt; @stories.to_xml<br />
}<br />
format.json {<br />
render :json =&gt; @stories.to_json<br />
}<br />
format.iphone {<br />
// Serve up the iPhone version<br />
}<br />
format.mobile {<br />
// Serve up the mobile version<br />
}<br />
}<br />
end</code>当然，必须在每个respond_to代码块用手工提交不同的版本的做法不太符合DRY原则，所以已经为所有的视图文件创建了一种新的命名惯例。相对于在上面的index.rhtml中调用视图文件，根据你要使用的方式建立三种不同的版本的视图文件更好，比如， index.html.erb, index.iphone.erb 和 index.mobile.erb。</p>
<p>当rails找到一个匹配的视图就使用它;当找不到时就使用默认的.html.erb或者.rhtml文件。这让你的站点方便地用不同的版本的视图提供服务。</p>
<p>PS：<br />
这篇文章有drive2me大哥帮我校对，谢谢drive2me帮我耐心地讲解，和校对。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/28/%e7%bf%bb%e8%af%91rails-20-features-multiple-views/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>三本大书来了</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/23/%e4%b8%89%e6%9c%ac%e5%a4%a7%e4%b9%a6%e6%9d%a5%e4%ba%86/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/23/%e4%b8%89%e6%9c%ac%e5%a4%a7%e4%b9%a6%e6%9d%a5%e4%ba%86/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 01:45:35 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Reading]]></category>
		<category><![CDATA[读书]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/23/%e4%b8%89%e6%9c%ac%e5%a4%a7%e4%b9%a6%e6%9d%a5%e4%ba%86/</guid>
		<description><![CDATA[   今天买的三本大书来了。邮局的快递下午送来的，三本，《Ruby cookbook》和《Rails cookbook》，还有《head first 设计模式》。Rail的cookbook是影印版，其他两本是中文版。
今晚看了Rail cookbook，看了第六章，讲REST的，每个Recipe都有一个生动的例子做解释，代码最具表现力的。过几天想把这一章翻译出来，放在论坛给大家看看。还有这本书感觉上和《Rails Recipes》很类似，虽然Recipes只是粗略地浏览一下而已，不过感觉是一样的。Cookbook和Recipes配合着《滑板之道》一起看好像效果比较好，因为Rails的每个特性，都在这两本书上有很好应用示例。这样的书里的只是很容易应用到实际开发上，嗯，实用主义。
Ruby Cookbook也是比较实用，我买这本书的用意就是想看看很多api的例子。我自己在写一个叫RStyle的项目，现在才0.1，是个代码格式化器，里面涉及了一个代码分析器。在写代码分析器时，我开始有点不知所措了，所以想找点Ruby编程的书看看，好像《Ruby Way》这本书里讲的一些数据结构也挺适合的，嗯下次买这本。还没有开始看，应该会很有趣。
《HF设计模式》就是我垂涎已久的书了，中文版跳票了很久，一年前就在等这本书的中文版，现在终于到手了。这系列的书就是有趣生动，多图片，一边学习一边玩，很好的感觉。比如适配器模式，这里的图片用了插座的例子，一个两头的插头，要插进一个三孔的插座，要怎么办？答案是用一个两头转三头的插头，是不是很生动？我一直在想设计模式在Ruby中会怎么表现，正好一边看这本书可以一边思考这个问题。
最近想看多一点源码，最近在看redmine的源码，觉得这个系统很经典，很多代码值得玩味，以后写点心得和研究出来。我要学多一点，写多一点，总结多一点，我要变得更厉害。
]]></description>
			<content:encoded><![CDATA[<p>   今天买的三本大书来了。邮局的快递下午送来的，三本，《Ruby cookbook》和《Rails cookbook》，还有《head first 设计模式》。Rail的cookbook是影印版，其他两本是中文版。<span id="more-47"></span></p>
<p>今晚看了Rail cookbook，看了第六章，讲REST的，每个Recipe都有一个生动的例子做解释，代码最具表现力的。过几天想把这一章翻译出来，放在论坛给大家看看。还有这本书感觉上和《Rails Recipes》很类似，虽然Recipes只是粗略地浏览一下而已，不过感觉是一样的。Cookbook和Recipes配合着《滑板之道》一起看好像效果比较好，因为Rails的每个特性，都在这两本书上有很好应用示例。这样的书里的只是很容易应用到实际开发上，嗯，实用主义。</p>
<p>Ruby Cookbook也是比较实用，我买这本书的用意就是想看看很多api的例子。我自己在写一个叫RStyle的项目，现在才0.1，是个代码格式化器，里面涉及了一个代码分析器。在写代码分析器时，我开始有点不知所措了，所以想找点Ruby编程的书看看，好像《Ruby Way》这本书里讲的一些数据结构也挺适合的，嗯下次买这本。还没有开始看，应该会很有趣。</p>
<p>《HF设计模式》就是我垂涎已久的书了，中文版跳票了很久，一年前就在等这本书的中文版，现在终于到手了。这系列的书就是有趣生动，多图片，一边学习一边玩，很好的感觉。比如适配器模式，这里的图片用了插座的例子，一个两头的插头，要插进一个三孔的插座，要怎么办？答案是用一个两头转三头的插头，是不是很生动？我一直在想设计模式在Ruby中会怎么表现，正好一边看这本书可以一边思考这个问题。</p>
<p>最近想看多一点源码，最近在看redmine的源码，觉得这个系统很经典，很多代码值得玩味，以后写点心得和研究出来。我要学多一点，写多一点，总结多一点，我要变得更厉害。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/23/%e4%b8%89%e6%9c%ac%e5%a4%a7%e4%b9%a6%e6%9d%a5%e4%ba%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>碰见鬼佬变成哑巴的故事</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/21/%e7%a2%b0%e8%a7%81%e9%ac%bc%e4%bd%ac%e5%8f%98%e6%88%90%e5%93%91%e5%b7%b4%e7%9a%84%e6%95%85%e4%ba%8b/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/21/%e7%a2%b0%e8%a7%81%e9%ac%bc%e4%bd%ac%e5%8f%98%e6%88%90%e5%93%91%e5%b7%b4%e7%9a%84%e6%95%85%e4%ba%8b/#comments</comments>
		<pubDate>Sat, 20 Oct 2007 18:48:33 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/21/%e7%a2%b0%e8%a7%81%e9%ac%bc%e4%bd%ac%e5%8f%98%e6%88%90%e5%93%91%e5%b7%b4%e7%9a%84%e6%95%85%e4%ba%8b/</guid>
		<description><![CDATA[昨天和同学去帮一个外教把Ubuntu搞上网，本来想着去到那里和他好好聊一下Ubuntu的相关话题的。

其实去到只是安装一个库（so）。他还叫了他一个朋友来帮忙，也是鬼佬。另外这个鬼佬比较厉害，他说他使用Linux From 1998，好像很厉害的样子，会用svn下载软件，对Linux的图形界面操作很熟，对命令行的操作就不熟。我同学感叹到，外国人对电脑这东西的熟悉程度比国人高太多了，从小就象一般家庭电器那样接触电脑。
其实很多地方我对他的操作有很多建议，但是都说不出，平时真是太少读口语。他问我改名的命令是什么，我回答是连V的发音都发不准，真失败。在外国佬面前我好像是个哑巴，太没用了。在平时我可以在不借助翻译软件的情况下看懂英文原版书的，也可以很好地翻译英文的，自认为是这样。好像我的英语能力还在书面英语阶段。
回来之后我很失落，而且下定决心要读多点英语。在整个暑假，我在背新概念英语，大概是两天一篇，看来成效还没有出现。以后没事不听歌了，听英语好了，一个星期要背两三篇新概念英语。在以后做软件开发这行的话，交流是很重要的，和客户交流，和团队中的同事交流，其中很难说没有外国人，那这样英语就是交流的重要工具了。我需要达到能独立和外国人用英语交流的水平。
我不想再在鬼佬面前当哑巴了。
]]></description>
			<content:encoded><![CDATA[<p>昨天和同学去帮一个外教把Ubuntu搞上网，本来想着去到那里和他好好聊一下Ubuntu的相关话题的。<br />
<span id="more-28"></span><br />
其实去到只是安装一个库（so）。他还叫了他一个朋友来帮忙，也是鬼佬。另外这个鬼佬比较厉害，他说他使用Linux From 1998，好像很厉害的样子，会用svn下载软件，对Linux的图形界面操作很熟，对命令行的操作就不熟。我同学感叹到，外国人对电脑这东西的熟悉程度比国人高太多了，从小就象一般家庭电器那样接触电脑。</p>
<p>其实很多地方我对他的操作有很多建议，但是都说不出，平时真是太少读口语。他问我改名的命令是什么，我回答是连V的发音都发不准，真失败。在外国佬面前我好像是个哑巴，太没用了。在平时我可以在不借助翻译软件的情况下看懂英文原版书的，也可以很好地翻译英文的，自认为是这样。好像我的英语能力还在书面英语阶段。</p>
<p>回来之后我很失落，而且下定决心要读多点英语。在整个暑假，我在背新概念英语，大概是两天一篇，看来成效还没有出现。以后没事不听歌了，听英语好了，一个星期要背两三篇新概念英语。在以后做软件开发这行的话，交流是很重要的，和客户交流，和团队中的同事交流，其中很难说没有外国人，那这样英语就是交流的重要工具了。我需要达到能独立和外国人用英语交流的水平。</p>
<p>我不想再在鬼佬面前当哑巴了。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/21/%e7%a2%b0%e8%a7%81%e9%ac%bc%e4%bd%ac%e5%8f%98%e6%88%90%e5%93%91%e5%b7%b4%e7%9a%84%e6%95%85%e4%ba%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新鲜出炉的Ubuntu7.10</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/19/%e6%96%b0%e9%b2%9c%e5%87%ba%e7%82%89%e7%9a%84ubuntu710/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/19/%e6%96%b0%e9%b2%9c%e5%87%ba%e7%82%89%e7%9a%84ubuntu710/#comments</comments>
		<pubDate>Thu, 18 Oct 2007 18:45:21 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/19/%e6%96%b0%e9%b2%9c%e5%87%ba%e7%82%89%e7%9a%84ubuntu710/</guid>
		<description><![CDATA[昨天18号，Ubuntu官方发布了Ubuntu的最新版本7.10。

昨天一大早我就在ubuntu中文社区和一大班人一边等一边jjww。等到中午时，我等不及了，就开始Upgrade了。好像cn99的源一直都连不上，只能用大陆的官方源来升级了。按照官方的说法是用更新管理器来做版本升级的，官源的速度不是很快只是一百多K而已。大概一个钟的时间就能完成版本的 upgrade，中间的时间去睡了一下下。
升级完重启，一堆问题开始来了。首先Grub只能认到整个扩展分区，认不到每个分区。不知是不是我的硬盘的分区表坏了。然后就是因为显卡驱动的原因，新内核进不去。再之后就是gnome不能启动，好在还有个xfce和fvwm，进去把Gnome重装一下，OK。进去Gnome后发现字体很难看，接着越调整越有问题，后来刷新了一下字体缓存就正常了。后来又发现Firefox的字体显示出来很小，调整了还是这样，卸了之后装了swiftfox好像好一点。不过用firefox看flash会假死。
完成了升级后，感觉变化不大，不过很明显新的Gnome的cpu占用小了，反应快了。还没有体验到新内核的提速，等到Ati的8.42.4来临再来。说到 8.42.4，ati拖了几天了，win的都出了好多天了，真是不公平。本来还想着U7.10能集成到新的官方驱动的，结果还是不行，只能寄望于8.04 了。
总的来说升级带来的问题不多，升级后的效果也不错，我升级的时候还很紧张呢：）
PS：这篇blog写了三次，第一次没有登录，登录完回来就没有，第二次时，快写完的时候开了InfoQ准备看flash，结果firefox死了。
]]></description>
			<content:encoded><![CDATA[<p>昨天18号，Ubuntu官方发布了Ubuntu的最新版本7.10。<br />
<span id="more-26"></span><br />
昨天一大早我就在ubuntu中文社区和一大班人一边等一边jjww。等到中午时，我等不及了，就开始Upgrade了。好像cn99的源一直都连不上，只能用大陆的官方源来升级了。按照官方的说法是用更新管理器来做版本升级的，官源的速度不是很快只是一百多K而已。大概一个钟的时间就能完成版本的 upgrade，中间的时间去睡了一下下。</p>
<p>升级完重启，一堆问题开始来了。首先Grub只能认到整个扩展分区，认不到每个分区。不知是不是我的硬盘的分区表坏了。然后就是因为显卡驱动的原因，新内核进不去。再之后就是gnome不能启动，好在还有个xfce和fvwm，进去把Gnome重装一下，OK。进去Gnome后发现字体很难看，接着越调整越有问题，后来刷新了一下字体缓存就正常了。后来又发现Firefox的字体显示出来很小，调整了还是这样，卸了之后装了swiftfox好像好一点。不过用firefox看flash会假死。</p>
<p>完成了升级后，感觉变化不大，不过很明显新的Gnome的cpu占用小了，反应快了。还没有体验到新内核的提速，等到Ati的8.42.4来临再来。说到 8.42.4，ati拖了几天了，win的都出了好多天了，真是不公平。本来还想着U7.10能集成到新的官方驱动的，结果还是不行，只能寄望于8.04 了。</p>
<p>总的来说升级带来的问题不多，升级后的效果也不错，我升级的时候还很紧张呢：）</p>
<p>PS：这篇blog写了三次，第一次没有登录，登录完回来就没有，第二次时，快写完的时候开了InfoQ准备看flash，结果firefox死了。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/19/%e6%96%b0%e9%b2%9c%e5%87%ba%e7%82%89%e7%9a%84ubuntu710/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu下开启compiz fusion效果图</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/09/ubuntu%e4%b8%8b%e5%bc%80%e5%90%afcompiz-fusion%e6%95%88%e6%9e%9c%e5%9b%be/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/09/ubuntu%e4%b8%8b%e5%bc%80%e5%90%afcompiz-fusion%e6%95%88%e6%9e%9c%e5%9b%be/#comments</comments>
		<pubDate>Mon, 08 Oct 2007 18:39:30 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[compiz]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/09/ubuntu%e4%b8%8b%e5%bc%80%e5%90%afcompiz-fusion%e6%95%88%e6%9e%9c%e5%9b%be/</guid>
		<description><![CDATA[前天用我的X1650GT和同学换了一块7300GT，在Ubuntu折腾了一下，终于如愿以偿地开启了Compiz Fusion的效果，并且用gDesklets在桌面加了一些实用工具挺好玩的。

过程也挺折腾的，先是安装了 ati的显卡驱动后要装nv的驱动碰到问题，然后再是开启特效后窗口没有了边框。在安装ati驱动后装nv的驱动先要删除几个库文件（libGL.so），看他提示哪个就删除哪个，然后nv驱动才可以正常安装。nv显卡开特效的边框的问题 只要运行一下sudo nvidia-xconfig &#8211;add-argb-glx-visuals就OK了。
现在上图看看：




]]></description>
			<content:encoded><![CDATA[<p>前天用我的X1650GT和同学换了一块7300GT，在Ubuntu折腾了一下，终于如愿以偿地开启了Compiz Fusion的效果，并且用gDesklets在桌面加了一些实用工具挺好玩的。<br />
<span id="more-23"></span><br />
过程也挺折腾的，先是安装了 ati的显卡驱动后要装nv的驱动碰到问题，然后再是开启特效后窗口没有了边框。在安装ati驱动后装nv的驱动先要删除几个库文件（libGL.so），看他提示哪个就删除哪个，然后nv驱动才可以正常安装。nv显卡开特效的边框的问题 只要运行一下sudo nvidia-xconfig &#8211;add-argb-glx-visuals就OK了。</p>
<p>现在上图看看：<br />
<img SRC="http://www.blogjava.net/images/blogjava_net/maninred/1.jpeg" /></p>
<p><img SRC="http://www.blogjava.net/images/blogjava_net/maninred/4.jpeg" /></p>
<p><img SRC="http://www.blogjava.net/images/blogjava_net/maninred/3.jpeg" HEIGHT="768" WIDTH="960" /></p>
<p><img SRC="http://www.blogjava.net/images/blogjava_net/maninred/2.jpeg" /></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/09/ubuntu%e4%b8%8b%e5%bc%80%e5%90%afcompiz-fusion%e6%95%88%e6%9e%9c%e5%9b%be/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby-lang上Ruby与Java的对比文章</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/09/ruby-lang%e4%b8%8aruby%e4%b8%8ejava%e7%9a%84%e5%af%b9%e6%af%94%e6%96%87%e7%ab%a0/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/09/ruby-lang%e4%b8%8aruby%e4%b8%8ejava%e7%9a%84%e5%af%b9%e6%af%94%e6%96%87%e7%ab%a0/#comments</comments>
		<pubDate>Mon, 08 Oct 2007 18:25:25 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/09/ruby-lang%e4%b8%8aruby%e4%b8%8ejava%e7%9a%84%e5%af%b9%e6%af%94%e6%96%87%e7%ab%a0/</guid>
		<description><![CDATA[原文地址
下午无聊翻译一下，看看ruby官方怎么和java对比

相同点：
类似于java，在ruby中：
内存管理都是由GC（garbage collector）负责。
都是强类型语言。
都有public，private，protected的方法可见性之分。
都有嵌入式文档工具（ruby的叫做RDoc）。rdoc生成的文档看起来非常像由javadoc生成的。
不同：
于java不同的是，在ruby中：
你不必编译代码，你只需要直接运行代码。
Gui开发包不同。比如，ruby的用户会尝试WxRuby，FXRuby，Ruby-GNOME2,或者基于Ruby Tk库。
你要在定义任何事物（像class）后面加上关键字end，而不是用花括号（{}）来包围代码块。
使用了require代替了import。
所有的成员变量（属性）都是private级的。在类外访问任何事物要通过方法调用。
什么都是对象，包括2和3.14159。
没有静态类型检查。
变量名都只是标签，它们没有与类型相关。
不用声明变量类型，你只需要赋值给新的变量名就可以了（例子，a = [1,2,3] 相当于 int[] a = {1,2,3};）。
没有类型强制转换这个概念，只管调用方法就好了。
用 foo = Foo.new( &#8220;hi&#8221;) 取代这样新建对象的方法 Foo foo = new Foo( &#8220;hi&#8221; )。
构造方法一直都叫“initialize”，不是和class同名的方法。
使用“混入” 代替 “接口”。
YAML 比 XML 更受欢迎。
这里用nil代替null。
==和equals()方法处理方法不同。当你想要测试相等性时就使用 == 操作符（就像Java的equals()方法）。当要想要知道两个对象是否是同一个时就使用equal?()方法(就像Java中的==)。 [点击图片可在新窗口打开]
]]></description>
			<content:encoded><![CDATA[<p><a HREF="http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-java/">原文地址</a><br />
下午无聊翻译一下，看看ruby官方怎么和java对比<br />
<span id="more-21"></span><br />
相同点：</p>
<p>类似于java，在ruby中：</p>
<p>内存管理都是由GC（garbage collector）负责。<br />
都是强类型语言。<br />
都有public，private，protected的方法可见性之分。<br />
都有嵌入式文档工具（ruby的叫做RDoc）。rdoc生成的文档看起来非常像由javadoc生成的。</p>
<p>不同：</p>
<p>于java不同的是，在ruby中：</p>
<p>你不必编译代码，你只需要直接运行代码。<br />
Gui开发包不同。比如，ruby的用户会尝试WxRuby，FXRuby，Ruby-GNOME2,或者基于Ruby Tk库。<br />
你要在定义任何事物（像class）后面加上关键字end，而不是用花括号（{}）来包围代码块。<br />
使用了require代替了import。<br />
所有的成员变量（属性）都是private级的。在类外访问任何事物要通过方法调用。<br />
什么都是对象，包括2和3.14159。<br />
没有静态类型检查。<br />
变量名都只是标签，它们没有与类型相关。<br />
不用声明变量类型，你只需要赋值给新的变量名就可以了（例子，a = [1,2,3] 相当于 int[] a = {1,2,3};）。<br />
没有类型强制转换这个概念，只管调用方法就好了。<br />
用 foo = Foo.new( &#8220;hi&#8221;) 取代这样新建对象的方法 Foo foo = new Foo( &#8220;hi&#8221; )。<br />
构造方法一直都叫“initialize”，不是和class同名的方法。<br />
使用“混入” 代替 “接口”。<br />
YAML 比 XML 更受欢迎。<br />
这里用nil代替null。<br />
==和equals()方法处理方法不同。当你想要测试相等性时就使用 == 操作符（就像Java的equals()方法）。当要想要知道两个对象是否是同一个时就使用equal?()方法(就像Java中的==)。 [点击图片可在新窗口打开]</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/09/ruby-lang%e4%b8%8aruby%e4%b8%8ejava%e7%9a%84%e5%af%b9%e6%af%94%e6%96%87%e7%ab%a0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>zhpy周蟒，实现用中文写代码的愿望</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/08/zhpy%e5%91%a8%e8%9f%92%ef%bc%8c%e5%ae%9e%e7%8e%b0%e7%94%a8%e4%b8%ad%e6%96%87%e5%86%99%e4%bb%a3%e7%a0%81%e7%9a%84%e6%84%bf%e6%9c%9b/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/08/zhpy%e5%91%a8%e8%9f%92%ef%bc%8c%e5%ae%9e%e7%8e%b0%e7%94%a8%e4%b8%ad%e6%96%87%e5%86%99%e4%bb%a3%e7%a0%81%e7%9a%84%e6%84%bf%e6%9c%9b/#comments</comments>
		<pubDate>Sun, 07 Oct 2007 18:36:08 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Promgramming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/08/zhpy%e5%91%a8%e8%9f%92%ef%bc%8c%e5%ae%9e%e7%8e%b0%e7%94%a8%e4%b8%ad%e6%96%87%e5%86%99%e4%bb%a3%e7%a0%81%e7%9a%84%e6%84%bf%e6%9c%9b/</guid>
		<description><![CDATA[周蟒是中文的Python，支持简体和繁体，用它就能进行中文来写代码。
周蟒的官方主页：
http://code.google.com/p/zhpy/


    簡介
    周蟒 (zhpy) 是一種簡單易學、功能強大的程式語言。它具有高效率的高階資料結構、簡單而有效的物件導向程式設計方式。並讓你可以使用純中文語句 (繁體或簡體) 來編寫程式。 馬上照著 咬一口周蟒語言 一書學習吧!
    周蟒是什麼?
        * 友善而易於學習的中文程式語言
        * 清晰可讀的語法
        * 直觀的物件導向能力
        * [...]]]></description>
			<content:encoded><![CDATA[<p>周蟒是中文的Python，支持简体和繁体，用它就能进行中文来写代码。</p>
<p>周蟒的官方主页：<br />
http://code.google.com/p/zhpy/<br />
<span id="more-22"></span></p>
<blockquote><p>
    簡介</p>
<p>    周蟒 (zhpy) 是一種簡單易學、功能強大的程式語言。它具有高效率的高階資料結構、簡單而有效的物件導向程式設計方式。並讓你可以使用純中文語句 (繁體或簡體) 來編寫程式。 馬上照著 咬一口周蟒語言 一書學習吧!<br />
    周蟒是什麼?</p>
<p>        * 友善而易於學習的中文程式語言<br />
        * 清晰可讀的語法<br />
        * 直觀的物件導向能力<br />
        * 方便的動態物件類型<br />
        * 透過模組有架構地組織程式<br />
        * 多平台適用(Windows, Linux, Mac)的程式語言<br />
        * 全功能的中文版本 Python 語言</p>
<p>    特點</p>
<p>        * 周蟒是全功能的 Python 程式語言。<br />
              o 周蟒本身就是個 python 模組<br />
              o 擁有所有 python 程式語言的功能與特性<br />
              o 可以在周蟒中使用所有的 python 模組<br />
        * 安裝容易<br />
              o 可使用 easy_install 命令線上安裝<br />
              o 檔案體積小 (=0.8)<br />
              o 可在作業系統中當作中文腳本執行<br />
              o 可在 Python 互動式直譯器中測試周蟒中文程式<br />
        * 擴充性好<br />
              o 可以混用繁簡中英 關鍵詞/保留字<br />
              o 可以自訂參考字表<br />
        * 發展性高<br />
              o 周蟒, python 程式碼可互相轉換 (&gt;=0.8)<br />
              o 可用周蟒程式碼生成英文 python source<br />
              o 可用 python 程式碼生成繁簡體周蟒程式<br />
              o 產生的 python source 可應用在任何 python 程式中<br />
              o zhpy 換上日韓關鍵字也可以擴展成日蟒, 韓蟒<br />
        * 完整測試<br />
              o 超過60筆單元測試(unittest)與文件測試(doctest)<br />
              o 完整的範例測試與命令行測試</p>
<p>    周蟒背後的哲學有三:</p>
<p>        * 把事情做好 (Getting Things Done)<br />
        * 程式碼被閱讀的機會比被修改的機會多 (Code is read much more than it it written)<br />
        * 一致的表達 (There should be one obvious way to do it)</p>
<p>    程式語言再怎麼修改得接近自然語言, 都仍然具有程式語言的邏輯與規則, 周蟒語言的目的並不是接近中文自然語言，而是做出一個實用的中文程式語言。</p>
<p>    周蟒的長處是在於發揮 &#8220;完全相容 Python 程式語言&#8221; 的中文程式語言的優點， 所有語法，關鍵詞都依照 Python 的風格。學習周蟒後要橋接到 Python 語言相當容易。</p>
<p>    由設計目的跟設計哲學產生出的周蟒，其寫作特色有：</p>
<p>        * Python 程式語言 + 中文支援<br />
        * 互動式直譯器<br />
        * 白話關鍵詞<br />
        * 縮排與關鍵詞前後留白<br />
        * 使用數學運算符號, 英文標點<br />
        * 較多的可參考文件
</p></blockquote>
<p>最简单的例子：<br />
<code>印出 '哈啰, 世界'</code><br />
这就是中文的HelloWorld，是不是看起来很有亲切感。这句和以下等价：<br />
<code>print '哈囉, 世界'</code><br />
函数定义也是中文的：<br />
<code><br />
#!/usr/bin/env zhpy<br />
# 檔名: function1.py<br />
定義 說哈囉():<br />
    印出 '哈囉, 世界!' # 函式主體<br />
說哈囉() # 呼叫函式<br />
</code><br />
想了解多一点可以看看这个“咬一口周蟒中文程式語言”教程，看看不会花很多时间，大概一个下午就可以了。</p>
<p>安装文件：<br />
http://zhpy.googlecode.com/files/zhpy-1.1.zip</p>
<p>api文档：<br />
http://zhpy.googlecode.com/files/apidocs1.1.zip</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/08/zhpy%e5%91%a8%e8%9f%92%ef%bc%8c%e5%ae%9e%e7%8e%b0%e7%94%a8%e4%b8%ad%e6%96%87%e5%86%99%e4%bb%a3%e7%a0%81%e7%9a%84%e6%84%bf%e6%9c%9b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TDDbyEx书中资金例子Ruby完整重现</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/10/03/tddbyex%e4%b9%a6%e4%b8%ad%e8%b5%84%e9%87%91%e4%be%8b%e5%ad%90ruby%e5%ae%8c%e6%95%b4%e9%87%8d%e7%8e%b0/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/10/03/tddbyex%e4%b9%a6%e4%b8%ad%e8%b5%84%e9%87%91%e4%be%8b%e5%ad%90ruby%e5%ae%8c%e6%95%b4%e9%87%8d%e7%8e%b0/#comments</comments>
		<pubDate>Wed, 03 Oct 2007 02:06:42 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/03/tddbyex%e4%b9%a6%e4%b8%ad%e8%b5%84%e9%87%91%e4%be%8b%e5%ad%90ruby%e5%ae%8c%e6%95%b4%e9%87%8d%e7%8e%b0/</guid>
		<description><![CDATA[早上看了blackanger写的TDD by Ex这本书里的资金例子，自己也想写一写。和他不同，我是全过程详细写出来。第一次用Ruby写代码，第一次用Ruby的Unit框架，而且下午睡醒后迷迷糊糊写的，可能有很多错误，请多多指正。

第一次迭代后的代码（简单的TDD代码）

# file tc_doller.rb
$:.unshift File.join(File.dirname(__FILE__), "..", "src")
require 'test/unit'
require 'dollar'
class TestMoney &#60; Test::Unit::TestCase
        def testMultiplication
                five = Dollar.new(5)
                [...]]]></description>
			<content:encoded><![CDATA[<p>早上看了<a HREF="http://www.ruby-lang.org.cn/forums/thread-1491-1-4.html">blackanger写的TDD by Ex这本书里的资金例子</a>，自己也想写一写。和他不同，我是全过程详细写出来。第一次用Ruby写代码，第一次用Ruby的Unit框架，而且下午睡醒后迷迷糊糊写的，可能有很多错误，请多多指正。<br />
<span id="more-3"></span><br />
第一次迭代后的代码（简单的TDD代码）<br />
<code><br />
# file tc_doller.rb<br />
$:.unshift File.join(File.dirname(__FILE__), "..", "src")<br />
require 'test/unit'<br />
require 'dollar'<br />
class TestMoney &lt; Test::Unit::TestCase<br />
        def testMultiplication<br />
                five = Dollar.new(5)<br />
                five.times(2)<br />
                assert_equal(10, five.amount)<br />
        end<br />
end</p>
<p># file doller.rb<br />
class Dollar<br />
        def initialize(amount)<br />
                @amount = amount<br />
        end<br />
        def times(multiplier)<br />
                @amount = @amount * multiplier<br />
        end<br />
        def amount<br />
                return @amount<br />
        end<br />
end</code><br />
第二次迭代后的代码<br />
<code><br />
# file tc_doller.rb<br />
$:.unshift File.join(File.dirname(__FILE__), "..", "src")<br />
require 'test/unit'<br />
require 'dollar'<br />
class TestMoney &lt; Test::Unit::TestCase<br />
        def testMultiplication<br />
                five = Dollar.new(5)<br />
                product = five.times(2)<br />
                assert_equal(10, product.amount)<br />
                product = five.times(3)<br />
                assert_equal(15, product.amount)<br />
        end<br />
end</p>
<p># file doller.rb<br />
class Dollar<br />
        attr_reader :amount<br />
        protected :amount<br />
        def initialize(amount)<br />
                @amount = amount<br />
        end</p>
<p>        def times(multiplier)<br />
                return Dollar.new @amount * multiplier<br />
        end<br />
end<br />
</code><br />
第三，四次迭代后的代码（添加了相等性测试，刚好Ruby中的equal?和==的语意和Java相反）<br />
<code><br />
# file tc_doller.rb<br />
$:.unshift File.join(File.dirname(__FILE__), "..", "src")<br />
require 'test/unit'<br />
require 'dollar'</p>
<p>class TestMoney &lt; Test::Unit::TestCase<br />
        def testMultiplication<br />
                five = Dollar.new(5)<br />
                product = five.times(2)<br />
                assert_equal(10, product.amount)<br />
                product = five.times(3)<br />
                assert_equal(15, product.amount)<br />
        end</p>
<p>        def testEquality<br />
                assert(Dollar.new(5) == Dollar.new(5))<br />
                assert(Dollar.new(5) != Dollar.new(6))<br />
        end</p>
<p>end</p>
<p># file doller.rb</p>
<p>class Dollar<br />
        attr_reader :amount<br />
        protected :amount</p>
<p>        def initialize(amount)<br />
                @amount = amount<br />
        end</p>
<p>        def times(multiplier)<br />
                return Dollar.new @amount * multiplier<br />
        end</p>
<p>        def ==(obj)<br />
                return obj.amount == @amount<br />
        end<br />
end<br />
</code><br />
第五，六，七次迭代后的代码（短命的Franc对象登场）<br />
<code><br />
# file tc_doller.rb</p>
<p>$:.unshift File.join(File.dirname(__FILE__), "..", "src")<br />
require 'test/unit'<br />
require 'money'<br />
require 'dollar'<br />
require 'franc'</p>
<p>class TestMoney &lt; Test::Unit::TestCase<br />
        def testMultiplication<br />
                five = Dollar.new(5)<br />
                assert_equal(Dollar.new(10), five.times(2))<br />
                assert_equal(Dollar.new(15), five.times(3))<br />
        end</p>
<p>        def testEquality<br />
                assert(Dollar.new(5) == Dollar.new(5))<br />
                assert(Dollar.new(5) != Dollar.new(6))<br />
                assert(Franc.new(5) == Franc.new(5))<br />
                assert(Franc.new(5) != Franc.new(6))<br />
                assert(Franc.new(5) != Dollar.new(5))<br />
        end</p>
<p>        def testFrancMultiplication<br />
                five = Franc.new(5)<br />
                assert_equal(Franc.new(10), five.times(2))<br />
                assert_equal(Franc.new(15), five.times(3))<br />
        end<br />
end</p>
<p># file doller.rb</p>
<p>class Dollar &lt; Money<br />
        def initialize(amount)<br />
                super(amount)<br />
        end</p>
<p>        def times(multiplier)<br />
                return Dollar.new(@amount * multiplier)<br />
        end<br />
end</p>
<p># file franc.rb</p>
<p>class Franc &lt; Money<br />
        def initialize(amount)<br />
                super(amount)<br />
        end</p>
<p>        def times(multiplier)<br />
                return Franc.new(@amount * multiplier)<br />
        end<br />
end</p>
<p># file money.rb</p>
<p>class Money<br />
        attr_reader :amount<br />
        protected :amount</p>
<p>        def initialize(amount)<br />
                @amount = amount<br />
        end</p>
<p>        def ==(obj)<br />
                return obj.amount.equal?(@amount)<br />
        end<br />
end<br />
</code><br />
第八，九，十，十一次迭代（消除子类，很巧妙的一步）<br />
<code><br />
# file tc_doller.rb</p>
<p>$:.unshift File.join(File.dirname(__FILE__), "..", "src")<br />
require 'test/unit'<br />
require 'money'</p>
<p>class TestMoney &lt; Test::Unit::TestCase<br />
        def testMultiplication<br />
                five = Money.dollar(5)<br />
                assert_equal(Money.dollar(10), five.times(2))<br />
                assert_equal(Money.dollar(15), five.times(3))<br />
        end</p>
<p>        def testFrancMultiplication<br />
                five = Money.franc(5)<br />
                assert_equal(Money.franc(10), five.times(2))<br />
                assert_equal(Money.franc(15), five.times(3))<br />
        end</p>
<p>        def testEquality<br />
                assert(Money.dollar(5) == Money.dollar(5))<br />
                assert(Money.dollar(5) != Money.dollar(6))<br />
                assert(Money.franc(5) != Money.dollar(5))<br />
        end</p>
<p>        def testCurrency<br />
                assert_equal("USD", Money.dollar(1).currency)<br />
                assert_equal("CHF", Money.franc(1).currency)<br />
        end<br />
end</p>
<p># file money.rb</p>
<p>class Money<br />
        attr_reader :amount, :currency<br />
        protected :amount</p>
<p>        def initialize(amount, currency)<br />
                @amount = amount<br />
                @currency = currency<br />
        end</p>
<p>        def self.dollar(amount)<br />
                return Money.new(amount, "USD")<br />
        end</p>
<p>        def self.franc(amount)<br />
                return Money.new(amount, "CHF")<br />
        end</p>
<p>        def times(multiplier)<br />
                return Money.new(@amount*multiplier, @currency)<br />
        end</p>
<p>        def plus(addend)<br />
                return Money.new(@amount + addend.amount, currency)<br />
        end</p>
<p>        def ==(obj)<br />
                return obj.amount.equal?(@amount) &amp;&amp; (obj.currency == @currency)<br />
        end<br />
end<br />
</code><br />
最后的一部分<br />
最后是完成不同货币之间的计算，引入了两个新的对象负责处理汇率的Bank和货币相加的Sum对象。</p>
<p>由于Ruby的动态性无须让Sum和Money实现同一接口，反正原书中的Expression对象也是为了Sum和Money对象可以通信。或许可以把Sum简化掉，有空时再想想。<br />
<code><br />
# file tc_doller.rb</p>
<p>$:.unshift File.join(File.dirname(__FILE__), "..", "src")<br />
require 'test/unit'<br />
require 'money'<br />
require 'bank'<br />
require 'sum'</p>
<p>class TestMoney &lt; Test::Unit::TestCase<br />
    def testDollarMultiplication<br />
        five = Money.dollar(5)<br />
        assert_equal(Money.dollar(10), five.times(2))<br />
        assert_equal(Money.dollar(15), five.times(3))<br />
    end</p>
<p>    def testFrancMultiplication<br />
        five = Money.franc(5)<br />
        assert_equal(Money.franc(10), five.times(2))<br />
        assert_equal(Money.franc(15), five.times(3))<br />
    end</p>
<p>    def testEquality<br />
        assert(Object.new != Money.dollar(1))<br />
        assert(Money.dollar(5) == Money.dollar(5))<br />
        assert(Money.dollar(5) != Money.dollar(6))<br />
        assert(Money.franc(5) != Money.dollar(5))<br />
    end</p>
<p>    def testCurrency<br />
        assert_equal("USD", Money.dollar(1).currency)<br />
        assert_equal("CHF", Money.franc(1).currency)<br />
    end</p>
<p>    def testSimpleAddition<br />
        five = Money.dollar(5)<br />
        sum = five.plus(Money.dollar(5))<br />
        bank = Bank.new()<br />
        reduced = bank.reduce(sum, "USD")<br />
        assert_equal(Money.dollar(10), reduced)<br />
    end</p>
<p>    def testReduceSum<br />
        sum = Sum.new(Money.dollar(3), Money.dollar(4))<br />
        bank = Bank.new()<br />
        result = bank.reduce(sum, "USD")<br />
        assert_equal(Money.dollar(7), result)<br />
    end</p>
<p>    def testReduceMoney<br />
        bank = Bank.new<br />
        result = bank.reduce(Money.dollar(1), "USD")<br />
        assert_equal(Money.dollar(1), result)<br />
    end</p>
<p>    def testReduceMoneyDiffentCurrency<br />
        bank = Bank.new<br />
        bank.addRate("CHF", "USD", 2)<br />
        result = bank.reduce(Money.franc(2), "USD")<br />
        assert_equal(Money.dollar(1), result)<br />
    end</p>
<p>    def testIndentityRate<br />
        bank = Bank.new<br />
        bank.addRate("USD", "CHF", 0.5)<br />
        assert_equal(1, bank.rate("USD", "USD"))<br />
        assert_equal(0.5, bank.rate("USD", "CHF"))<br />
        assert_equal(2, bank.rate("CHF", "USD"))<br />
    end</p>
<p>    def testMixedAddition<br />
        fiveBucks = Money.dollar(5)<br />
        tenFrancs = Money.franc(10)<br />
        bank = Bank.new<br />
        bank.addRate("CHF", "USD", 2)<br />
        result = bank.reduce(fiveBucks.plus(tenFrancs), "USD")<br />
        assert_equal(Money.dollar(10), result)<br />
    end</p>
<p>    def testSumTimes<br />
        fiveBucks = Money.dollar(5)<br />
        tenFrancs = Money.franc(10)<br />
        bank = Bank.new<br />
        bank.addRate("CHF", "USD", 2)<br />
        sum = Sum.new(fiveBucks, tenFrancs).times(2)<br />
        result = bank.reduce(sum, "USD")<br />
        assert_equal(Money.dollar(20), result)<br />
    end<br />
end<br />
# file money.rb</p>
<p>class Money<br />
    attr_reader :amount, :currency</p>
<p>    def initialize(amount, currency)<br />
        @amount = amount<br />
        @currency = currency<br />
    end</p>
<p>    def self.dollar(amount)<br />
        return Money.new(amount, "USD")<br />
    end</p>
<p>    def self.franc(amount)<br />
        return Money.new(amount, "CHF")<br />
    end</p>
<p>    def times(multiplier)<br />
        return Money.new(@amount*multiplier, @currency)<br />
    end</p>
<p>    def plus(addend)<br />
        return Sum.new(self, addend)<br />
    end</p>
<p>    def ==(obj)<br />
        return obj.amount.equal?(@amount) &amp;&amp; (obj.currency == @currency)<br />
    end</p>
<p>    def reduce(bank, to)<br />
        rate = bank.rate(@currency, to)<br />
        return Money.new(@amount / rate, to)<br />
    end<br />
end<br />
# file bank.rb</p>
<p>class Bank<br />
    attr_accessor :rates<br />
    @@rates = {}</p>
<p>    def reduce(source, to)<br />
        return source.reduce(self, to)<br />
    end</p>
<p>    def addRate(from, to, rate)<br />
        @@rates["#{from}-#{to}"] = rate<br />
        @@rates["#{to}-#{from}"] = 1 / rate<br />
    end</p>
<p>    def rate(from, to)<br />
        return 1 if(from == to)<br />
        return @@rates["#{from}-#{to}"]<br />
    end<br />
end<br />
# file sum.rb</p>
<p>class Sum<br />
    attr_reader :augend, :addend</p>
<p>    def initialize(augend, addend)<br />
        @augend = augend<br />
        @addend = addend<br />
    end</p>
<p>    def reduce(bank, to)<br />
        amount = augend.reduce(bank, to).amount + addend.reduce(bank, to).amount<br />
        return Money.new(amount, to)<br />
    end</p>
<p>    def times(multiplier)<br />
        return Sum.new(augend.times(multiplier), addend.times(multiplier))<br />
    end<br />
end</code></p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/10/03/tddbyex%e4%b9%a6%e4%b8%ad%e8%b5%84%e9%87%91%e4%be%8b%e5%ad%90ruby%e5%ae%8c%e6%95%b4%e9%87%8d%e7%8e%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用Ubuntu一个多星期感受</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/09/10/%e7%94%a8ubuntu%e4%b8%80%e4%b8%aa%e5%a4%9a%e6%98%9f%e6%9c%9f%e6%84%9f%e5%8f%97/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/09/10/%e7%94%a8ubuntu%e4%b8%80%e4%b8%aa%e5%a4%9a%e6%98%9f%e6%9c%9f%e6%84%9f%e5%8f%97/#comments</comments>
		<pubDate>Sun, 09 Sep 2007 18:44:04 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/09/10/%e7%94%a8ubuntu%e4%b8%80%e4%b8%aa%e5%a4%9a%e6%98%9f%e6%9c%9f%e6%84%9f%e5%8f%97/</guid>
		<description><![CDATA[用了Ubuntu7.04一个多星期了觉得挺很不错，很多方面比在windows下好很多。方便的硬盘安装。一开始是在家里的电脑安装的，之后把硬盘拿到学校的电脑一插上去就可以用了，只需在命令行界面配置显卡和校园网就OK了。Ubuntu的硬件的兼容性真是没得说，还有人还制作了一个可以放在U盘的精简版本。Linux的整个系统加上所有的常用软件比windows加上所有常用软件的磁盘占用小很多。
记得刚刚接触电脑的时候就用了一段时间的RH9,觉得很神秘很帅。后来来到学校后发现校园网上不到网，用xrgsu要么掉线要么上不到，试了sesu和fc 都是这样。因为万恶的锐捷又不能用虚拟机上网。这次是因为有个师兄用ubuntu7.04成功的上到了所以我又用回了Linux，用回了久违的VI。我不知为什么学了vi和emacs两个编辑器，但是一直都用不惯emacs，vi就用得很顺手。Linux下的编辑器就好在可以双手不离开键盘，不用去用到鼠标，不过太久没有用了，时不时手还是会想去摸鼠标，然后想一想手又缩回来按快捷键。
Ubuntu的中文社区很活跃，中文的资料又多得不得了，一般有什么问题搜索一下就可以查找到。
Ubuntu下用得最爽的是FireFox，好像没有windows下的内存泄漏现象。Linux下的BT软件就不怎样，还是用wine+比特精灵比较好。相对于bt，linux下的电驴软件就很厉害了，MLDonkey很快，最高能过1M/s。
下载安装软件，Ubuntu继承了Debian系的apt-get系列的方便，很大得方便了我这类懒人。只要一个命令就可以简单地在非图形界面安装软件，而且自动安装软件源中最新的版本，一并安装配置。只是把软件安装到哪里要自己去查找，有时是挺麻烦的，比如在安装后要修改配置文件的时候，特别是安装时文件分得很散，在配置radrails时要求输入rails和rake的路径。不过用了一段时间后熟悉了目录的配置之后就要找程序文件就简单多了，程序文件一般放在/usr/bin下。
不过有时一些软件还是自己手动安装好。第一有个权限问题，我的电脑还是主要用来做开发和学习的，而且又是我自己一个人用，对于Linux系统一向来的用户安全机制对我来说有点多余。自动安装的一些软件，有时要设置权限，比较麻烦。第二就是版本问题，软件源里的软件虽说都是稳定版本，但是我有时想要新一点的版本，比如Eclilpse3.3,NetBeans6。
在开发时最大的好处就是编码问题在 Linux下对utf-8的支持很好。还有好像一些ide在Linux下好像速度快一点，还有ruby也是，反应快了很多。正在试着Gvim+ rails.vim的感觉。不过还是习惯eclipse。Linux下的软件，要么是gtk的，要么是Qt，要么java的，感觉上至少比win32程序用起来觉得舒服一点，完全是心理作用。
最后有两件事让我不爽，一个是特效开不到，我的显卡是Ati 的X1650,万恶的ati官方驱动不支持XGL，开源驱动又不支持X1650。另一件事是我用eva和QQ2006上了几天之后登录的时候竟然说我“您的IP不能用低版本的QQ”，真是万恶的腾讯。我最后找了飘云版的QQ2007（因为不带键盘锁）才能用wine跑QQ2007。用wine+qq的时候发现打字那个提示框很快会不见，我用的是fcitx，还有我不能发起语音请求，发起时qq会崩溃，别人发起我接受就正常。
Ubuntu好好玩。
]]></description>
			<content:encoded><![CDATA[<p>用了Ubuntu7.04一个多星期了觉得挺很不错，很多方面比在windows下好很多。方便的硬盘安装。一开始是在家里的电脑安装的，之后把硬盘拿到学校的电脑一插上去就可以用了，只需在命令行界面配置显卡和校园网就OK了。Ubuntu的硬件的兼容性真是没得说，还有人还制作了一个可以放在U盘的精简版本。Linux的整个系统加上所有的常用软件比windows加上所有常用软件的磁盘占用小很多。</p>
<p>记得刚刚接触电脑的时候就用了一段时间的RH9,觉得很神秘很帅。后来来到学校后发现校园网上不到网，用xrgsu要么掉线要么上不到，试了sesu和fc 都是这样。因为万恶的锐捷又不能用虚拟机上网。这次是因为有个师兄用ubuntu7.04成功的上到了所以我又用回了Linux，用回了久违的VI。我不知为什么学了vi和emacs两个编辑器，但是一直都用不惯emacs，vi就用得很顺手。Linux下的编辑器就好在可以双手不离开键盘，不用去用到鼠标，不过太久没有用了，时不时手还是会想去摸鼠标，然后想一想手又缩回来按快捷键。</p>
<p>Ubuntu的中文社区很活跃，中文的资料又多得不得了，一般有什么问题搜索一下就可以查找到。</p>
<p>Ubuntu下用得最爽的是FireFox，好像没有windows下的内存泄漏现象。Linux下的BT软件就不怎样，还是用wine+比特精灵比较好。相对于bt，linux下的电驴软件就很厉害了，MLDonkey很快，最高能过1M/s。</p>
<p>下载安装软件，Ubuntu继承了Debian系的apt-get系列的方便，很大得方便了我这类懒人。只要一个命令就可以简单地在非图形界面安装软件，而且自动安装软件源中最新的版本，一并安装配置。只是把软件安装到哪里要自己去查找，有时是挺麻烦的，比如在安装后要修改配置文件的时候，特别是安装时文件分得很散，在配置radrails时要求输入rails和rake的路径。不过用了一段时间后熟悉了目录的配置之后就要找程序文件就简单多了，程序文件一般放在/usr/bin下。</p>
<p>不过有时一些软件还是自己手动安装好。第一有个权限问题，我的电脑还是主要用来做开发和学习的，而且又是我自己一个人用，对于Linux系统一向来的用户安全机制对我来说有点多余。自动安装的一些软件，有时要设置权限，比较麻烦。第二就是版本问题，软件源里的软件虽说都是稳定版本，但是我有时想要新一点的版本，比如Eclilpse3.3,NetBeans6。</p>
<p>在开发时最大的好处就是编码问题在 Linux下对utf-8的支持很好。还有好像一些ide在Linux下好像速度快一点，还有ruby也是，反应快了很多。正在试着Gvim+ rails.vim的感觉。不过还是习惯eclipse。Linux下的软件，要么是gtk的，要么是Qt，要么java的，感觉上至少比win32程序用起来觉得舒服一点，完全是心理作用。</p>
<p>最后有两件事让我不爽，一个是特效开不到，我的显卡是Ati 的X1650,万恶的ati官方驱动不支持XGL，开源驱动又不支持X1650。另一件事是我用eva和QQ2006上了几天之后登录的时候竟然说我“您的IP不能用低版本的QQ”，真是万恶的腾讯。我最后找了飘云版的QQ2007（因为不带键盘锁）才能用wine跑QQ2007。用wine+qq的时候发现打字那个提示框很快会不见，我用的是fcitx，还有我不能发起语音请求，发起时qq会崩溃，别人发起我接受就正常。</p>
<p>Ubuntu好好玩。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/09/10/%e7%94%a8ubuntu%e4%b8%80%e4%b8%aa%e5%a4%9a%e6%98%9f%e6%9c%9f%e6%84%9f%e5%8f%97/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>这个暑假</title>
		<link>http://redworld.blog.ubuntu.org.cn/2007/08/10/%e8%bf%99%e4%b8%aa%e6%9a%91%e5%81%87/</link>
		<comments>http://redworld.blog.ubuntu.org.cn/2007/08/10/%e8%bf%99%e4%b8%aa%e6%9a%91%e5%81%87/#comments</comments>
		<pubDate>Fri, 10 Aug 2007 08:43:02 +0000</pubDate>
		<dc:creator>maninred</dc:creator>
				<category><![CDATA[Thinking]]></category>
		<category><![CDATA[假期]]></category>

		<guid isPermaLink="false">http://redworld.blog.ubuntu.org.cn/2007/10/09/%e8%bf%99%e4%b8%aa%e6%9a%91%e5%81%87/</guid>
		<description><![CDATA[这个暑假过了一大半了，过得比较郁闷。

今天是暑假第一次在家上网，因为家里电脑坏了，主板拿去保修，修了20天后拿回来发现坏得更严重，又要不知道修到什么时候。（体验了华硕的售后实在不敢恭维）只好上个星期叫同学在网上帮我买了块二手主板，现在终于有电脑用一下。
暑假前已经计划好了要做什么，就是要把这个学期还没有做好的几个应用做好它，把picocontainer的1.0版的代码分析和文档汉化做完（在期末考试前因为无聊所以就做了这个事），还有再写一些有趣的代码，比如一个简单的XML仓库。
读书的计划提前完成了，看完了《领域模型驱动》，《web开发敏捷之道》（新鲜热辣），《Ruby for rails》。看了一半《对象设计》，还有把《重构》又看了一遍。
还好带了一些英语资料，手机里也存了一些英语的对话，每天背一篇短文，没事练习听着英语大声念几句。感觉还好。
今天看了一下敏捷大会的消息，又看了一下Thoughtworks里的强人的博客，觉得毕业后去那里的希望很渺茫。英语又差，技术和那些强人差了几个数量级，看来要更加更加努力。
]]></description>
			<content:encoded><![CDATA[<p>这个暑假过了一大半了，过得比较郁闷。<br />
<span id="more-24"></span><br />
今天是暑假第一次在家上网，因为家里电脑坏了，主板拿去保修，修了20天后拿回来发现坏得更严重，又要不知道修到什么时候。（体验了华硕的售后实在不敢恭维）只好上个星期叫同学在网上帮我买了块二手主板，现在终于有电脑用一下。</p>
<p>暑假前已经计划好了要做什么，就是要把这个学期还没有做好的几个应用做好它，把picocontainer的1.0版的代码分析和文档汉化做完（在期末考试前因为无聊所以就做了这个事），还有再写一些有趣的代码，比如一个简单的XML仓库。</p>
<p>读书的计划提前完成了，看完了《领域模型驱动》，《web开发敏捷之道》（新鲜热辣），《Ruby for rails》。看了一半《对象设计》，还有把《重构》又看了一遍。</p>
<p>还好带了一些英语资料，手机里也存了一些英语的对话，每天背一篇短文，没事练习听着英语大声念几句。感觉还好。</p>
<p>今天看了一下敏捷大会的消息，又看了一下Thoughtworks里的强人的博客，觉得毕业后去那里的希望很渺茫。英语又差，技术和那些强人差了几个数量级，看来要更加更加努力。</p>
]]></content:encoded>
			<wfw:commentRss>http://redworld.blog.ubuntu.org.cn/2007/08/10/%e8%bf%99%e4%b8%aa%e6%9a%91%e5%81%87/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	Recent Posts: <ol><li><a href="http://redworld.blog.ubuntu.org.cn/2008/08/22/blog%e5%b7%b2%e6%90%ac%e8%bf%81/" rel="bookmark" title="Permanent Link: Blog已搬迁">Blog已搬迁</a> - 2008-08-22</li><li><a href="http://redworld.blog.ubuntu.org.cn/2008/08/06/a-few-interesting-rails-plugin/" rel="bookmark" title="Permanent Link: a few interesting rails plugin">a few interesting rails plugin</a> - 2008-08-06</li><li><a href="http://redworld.blog.ubuntu.org.cn/2008/08/06/get-start-java-network-app-dev/" rel="bookmark" title="Permanent Link: Get Start Java Network App Dev">Get Start Java Network App Dev</a> - 2008-08-06</li><li><a href="http://redworld.blog.ubuntu.org.cn/2008/07/28/%e6%80%9d%e8%80%83%e7%9d%80blog%e6%90%ac%e5%ae%b6/" rel="bookmark" title="Permanent Link: 思考着Blog搬家">思考着Blog搬家</a> - 2008-07-28</li><li><a href="http://redworld.blog.ubuntu.org.cn/2008/07/28/a-bug-in-attachment_fu/" rel="bookmark" title="Permanent Link: a bug in attachment_fu ">a bug in attachment_fu </a> - 2008-07-28</li></ol></channel>
</rss>
