<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>AllenYoung</title>
    <description>我想涂去一切不幸
我想在大地上
画满窗子
让所有习惯黑暗的眼睛
都习惯光明</description>
    <link>http://allenyoung.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>梦回唐朝</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/209504" style="color:red;">http://allenyoung.javaeye.com/blog/209504</a>&nbsp;
          发表时间: 2008年06月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>唐朝乐队出新专辑了。看到这条新闻的时候心里不禁波动了一下，10年过去了，又听到了这个熟悉的名字---唐朝。想想看第一次听唐朝的歌还是在初中的时候，揣着好长时间才节省下来的10块钱，兴冲冲的去买正版的《梦回唐朝》磁带，之后晚上小心翼翼的塞到随身听里面团在被窝里悄悄的听。现在想想真是好久之前的事情了。</p>
<p>&nbsp;</p>
<p>现在，唐朝出新专辑了。我真有一种说不出的感觉，就好像青春期暗恋了很久的一个女孩子在消失了许久后突然又跟你联系了。我想这时候大多数人的心情一定是即激动又胆怯，激动的是你曾经爱恋的人又要即将出现在你面前，胆怯的是你一定会担心她是否已经面目全非，和你心中一直保留的形象相去甚远。</p>
<p>&nbsp;</p>
<p>我就是带着这种复杂的心情听完《浪漫骑士》这张新专辑的。总体感觉还不错，旋律很优美，歌词也保留了唐朝一直以来诗一般的意境。丁武的嗓子依然嘹亮，只是少了年轻时的高亢；老五的吉他依旧犀利，赵年的鼓声依旧稳重，陈磊和顾忠虽不是唐朝的开国之臣，但也跟随乐队走过了快10年头。听着耳机里传来的旋律，我突然想起了英年早逝的张炬。我实在忘不了这个家伙，不是因为他的贝斯弹得有多好（他贝斯确实好，但是我这种人是听不太出的），而是因为他在《梦回唐朝》封面上的表情太过犹豫了，让我永远不能忘记。</p>
<p>&nbsp;</p>
<p>我猜想，和我年龄相仿的同志们一定记得唐朝这个名字，1992年横空出世的重金属专辑《梦回唐朝》一度把这支年轻的乐队推向亚洲通俗文化的顶峰。想当年，这4个身高超过1米8长发过肩的汉子齐齐的站在舞台上，用高亢的嗓子、绚烂的吉他、磅礴的旋律和诗一般的唱词亮相于世人眼前时，所有人都被震撼了。唐朝，这个名字最好的描述了他们音乐的特点，大气磅礴、心旷神怡！丁武京剧化的唱腔和念白加上老五神乎其神的吉他演奏，让大家仿佛看到了中国摇滚的盛世即将来临。好评如潮水般涌来，甚至连香港红勘体育馆也为他们敞开了大门。唐朝横空出世！谁与争锋！</p>
<p>&nbsp;</p>
<p>然而，唐朝的第二张专辑《演义》确一直让人们等到了1999年。在这7年之间，贝斯手张炬在1995年因车祸逝世（不禁让我想起张雨生），这对乐队肯定是个不小的打击。但是在蛰伏了7年之久后才推出第二张专辑，不得不说唐朝的创作周期太长了。《演绎》从各个方面都无法与《梦回唐朝》相比，丁武似乎想在这张专辑中实验更多的音乐元素和诠释方法，但显然他对这些东西的掌握并没有完善到可以出专辑的程度。</p>
<p>&nbsp;</p>
<p>再以后呢？唐朝消失了...一连10年几乎没有一点儿消息，知道前不久，唐朝终于携《浪漫骑士》再度闯进人民的视线。让我们来看看吧：1988年组建乐队、1992年《梦回唐朝》、1999年《演义》、2008年《浪漫骑士》。整整20年，只有3张专辑...</p>
<p>&nbsp;</p>
<p>我要替在座的铁杆乐迷和曾经的铁杆乐迷问一句：你们这帮老兄都死哪儿去了？！</p>
<p>&nbsp;</p>
<p>看看乐队的官方介绍吧：乐队一直都很困难。很简单的解释，但是很难让人信服。翻开唐朝乐队的大事记，几乎都是演出，各种知名的、不知名的演出。我觉得这多少有些悲哀。一个一出场就造就经典的乐队、一个曾经引领亚洲通俗文化的乐队、一个造就了史上最佳100张中文专辑之一的乐队，竟然要在大事记上写&ldquo;上某时到某地某酒吧演出&rdquo;这样的事儿。</p>
<p>&nbsp;</p>
<p>我一直搞不懂中国摇滚。让我们看看中国摇滚史上那些赫赫有名的人，崔健、黑豹、唐朝、窦唯、张楚、何勇，等等等等。几乎都是第一张专辑横空出世，被奉为经典，之后就逐渐销声匿迹了。好一些的像崔健、黑豹、窦唯，作品也是少得可怜。再看看世界上那些老牌的摇滚音乐人，屹立几十年不倒，专辑少说也有十几张，几十张的也大有人在。我们这些同志们都怎么了呢？</p>
<p>&nbsp;</p>
<p>不想说唐朝的坏话，只是觉得很惋惜。曾经是一群很有想法、很有激情的年轻人，却荒废了那么长时间，非要到奔5的年龄了，才凑热闹一样的再发行专辑。真是可惜...</p>
<p>&nbsp;</p>
<p>最后附上《梦回唐朝》个歌词，也许我们只能回到那个躁动的年代，才能感受到真正赤裸裸的激情了。</p>
<p>&nbsp;</p>
<p>菊花古剑和酒 被咖啡泡入喧嚣的亭院<br />
异族在日坛膜拜古人的月亮 开元盛事令人神往<br />
<br />
风 吹不散长恨<br />
花 染不透乡仇<br />
雪 映不出山河<br />
月 圆不了古梦<br />
<br />
沿着掌纹烙着宿命 今宵酒醒无梦<br />
沿着宿命走入迷思 梦里回到唐朝<br />
<br />
今宵杯中映着明月 男耕女织丝路繁忙<br />
今宵杯中映着明月 物华天宝人杰地灵<br />
今宵杯中映着明月 纸香墨飞词赋满江<br />
今宵杯中映着明月 豪杰英气大千锦亮<br />
今宵杯中映不出明月 霓虹闪烁歌舞升平<br />
只因那五音不全的故事 木然唱合没人失落甚麽<br />
<br />
沿着掌纹烙着宿命 今宵酒醒无梦<br />
沿着宿命走入迷思 梦里回到唐朝<br />
<br />
忆昔开元全盛日 天下朋友皆胶漆<br />
眼界无穷世界宽 安得广厦千万间<br />
<br />
沿着掌纹烙着宿命 今宵酒醒无梦<br />
沿着宿命走入迷思 梦里回到唐朝<br />
<br />
今宵杯中映着明月 纸香墨飞词赋满江<br />
今宵杯中映着明月 豪杰英气大千锦亮<br />
<br />
沿着掌纹烙着宿命 今宵酒醒无梦<br />
沿着宿命走入迷思 彷佛回到梦里唐朝</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/209504#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 29 Jun 2008 19:36:56 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/209504</link>
        <guid>http://allenyoung.javaeye.com/blog/209504</guid>
      </item>
      <item>
        <title>Flex中实现跨域web service调用时crossdomain.xml的issue</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/207026" style="color:red;">http://allenyoung.javaeye.com/blog/207026</a>&nbsp;
          发表时间: 2008年06月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>玩过Flex或者Flash的同学都知道，如果想要在Flash里面跨域获取数据，就必须在对方server上配置crossdomain.xml。具体来说，比如你的Flash在domain A下面，而你想要访问domain B暴露的web service，那么domain B的server根目录下必须要有一个crossdomain.xml文件来配置说你有这个权限。这个是Flash Player的安全限制。</p>
<p>&nbsp;</p>
<p>对于Flash Player 9之前的版本，这个crossdomain.xml文件大概如下：</p>
<pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE cross-domain-policy SYSTEM
	&quot;http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd&quot; &gt;
&lt;cross-domain-policy&gt;
	&lt;allow-access-from domain=&quot;*&quot; secure=&quot;true&quot; /&gt;
&lt;/cross-domain-policy&gt;</pre>
<p>&nbsp;以上配置允许所有domain访问当前server所暴露的数据（比如web service）。你可以在domain属性里面指定特殊的规则。secure属性用来设置你所暴露的数据是否走https协议。</p>
<p>&nbsp;</p>
<p>但是对于Flash Player 9而言，crossdomain.xml文件内容出现了较大的变化，原因是Flash Player 9的security机制有所改变。所以当我用Flex 3调用cross domain的web service时，还使用上面的crossdomain.xml文件，结果就报错说security error。于是稍微研究了一下，得到如下解决方案，其实就是要改变crossdomain.xml的内容：</p>
<pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE cross-domain-policy SYSTEM
	&quot;http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd&quot; &gt;
&lt;cross-domain-policy&gt;
	&lt;site-control permitted-cross-domain-policies=&quot;all&quot; /&gt;
	&lt;allow-access-from domain=&quot;*&quot; /&gt;
	&lt;allow-http-request-headers-from domain=&quot;*&quot; headers=&quot;*&quot;/&gt;
&lt;/cross-domain-policy&gt;</pre>
<p>&nbsp;以上是Flash Player 9所要求的crossdomain.xml的内容。可以看到多了两个tag。其中site-control是可选的，但是allow-http-request-headers-from对于cross domain的web service确实必须的。如果没有允许header，就会像我之前一样报错。这些配置项的具体含义以及其他可选配置项，可以参考<a href="http://www.adobe.com/devnet/flashplayer/articles/flash_player_9_security.pdf" title="WHITE PAPER - Adobe Flash Player 9 Security" target="_blank">http://www.adobe.com/devnet/flashplayer/articles/flash_player_9_security.pdf</a>
</p>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/207026#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 23 Jun 2008 10:48:34 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/207026</link>
        <guid>http://allenyoung.javaeye.com/blog/207026</guid>
      </item>
      <item>
        <title>你知道正则表达式的形式化定义吗？</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/168360" style="color:red;">http://allenyoung.javaeye.com/blog/168360</a>&nbsp;
          发表时间: 2008年03月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-family: courier new,courier">正则表达式想必大家都用过，确实是很好很强大的东东。但是正则表达式的形式化定义各位知道吗？最近无聊看一本编译方面的书时，里面正好讲到了这个，还是挺有意思的。发出来和大家分享。</span></p><p><span style="font-family: courier new,courier">&nbsp;</span></p><p><span style="font-family: courier new,courier">首先，正则表达式是一种符号表示法，是为了用有限的描述来详细说明（可能）无限的语言。也就是说正则表达式是针对某个特定语言的，可以说每个正则表达式都定义了一种语言。每个正则表达式代表一个字符集。在正则表达式中，需要定义如下几个概念：</span></p><ul><li><span style="font-family: courier new,courier">符号：对语言字母表中的每个符号a，正则表达式a表示仅包含字符串a的语言。</span></li><li><span style="font-family: courier new,courier">或：对于给定的两个正则表达式M和N，可以利用或操作（|）连接为一个新的正则表达式：M|N。若一个字符串属于语言M或语言N，那么此串也属于语言M|N。因此，语言a|b包含两个字符串a和b。</span></li><li><span style="font-family: courier new,courier">并：对于给定的两个正则表达式M和N，可以利用并操作（<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&middot;</span>）将其连接为新的正则表达式M<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&middot;</span>N。设<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&alpha;</span>是语言M的字符串，<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&beta;</span>是语言N的字符串，若一个字符串是<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&alpha;</span>与<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&beta;</span>的并，那么这个字符串属于语言M<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&middot;</span>N。因此，正则表达式(a|b)<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&middot;</span>a定义包含两个字符串aa和ba的语言。</span></li><li><span style="font-family: courier new,courier"><span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&epsilon;</span>：正则表达式<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&epsilon;</span>代表了一个只包含空串的语言。因此(a<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&middot;</span>b)|<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&epsilon;</span>表示语言{&quot;&quot;, &quot;ab&quot;}。</span></li><li><span style="font-family: courier new,courier">重复：对于正则表达式M，其Kleene闭包是M*。若一个字符串为空或者它是M中所有字符串经过并操作所得到的结果，那么它就属于M*。</span></li></ul><p><span style="font-family: courier new,courier">以上这些概念就完整的定义了正则表达式，其中并没有我们所熟悉的那一套规则。不过其实那些规则都是用以上这些概念推导出来的，下面举几个简单的例子。在举例之前，再交代一下，并操作符和<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&epsilon;</span>在书写时是可以省略的，而Kleene闭包的优先级高于并操作，并操作的优先级高于或操作。</span></p><ul><li><span style="font-family: courier new,courier">[abcd] =&gt; (a|b|c|d)</span></li><li><span style="font-family: courier new,courier">[b-g] =&gt; [bcdefg]</span></li><li><span style="font-family: courier new,courier">[b-gM-Qkr] =&gt; [bcdefgMNOPQkr]</span></li><li>M+ =&gt; <span style="font-family: courier new,courier">(M<span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&middot;</span>M*)</span></li><li>M? =&gt; (M|<span style="font-family: courier new,courier"><span style="font-size: 11pt; line-height: 115%; font-family: 'Calibri','sans-serif'">&epsilon;</span></span>)</li></ul><p>你看，现在的正在表达式已经像回事儿了。接下去要做的无非就是引入特殊字符（.，\w，\s之类的）、贪婪模式、分组匹配等东东，不过核心的形式化模型就是上面的那些概念。</p><p>&nbsp;</p><p>还真是佩服研究这种东西的人，可以把一个东东做的在理论和实战领域都这么优雅。</p>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/168360#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 05 Mar 2008 16:25:54 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/168360</link>
        <guid>http://allenyoung.javaeye.com/blog/168360</guid>
      </item>
      <item>
        <title>在Leopard上使用NetBeans Ruby IDE</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/156837" style="color:red;">http://allenyoung.javaeye.com/blog/156837</a>&nbsp;
          发表时间: 2008年01月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本来像NetBeans这样到东东，应该是装上就可以用到。但是在Leopard上就是有些问题出在gem上面。Leopard上默认的gem目录是系统目录，而NetBeans管理gem的时候需要写权限，于是就会报错了。典型的情况就是安装ruby-debug-ide的时候。<br /><br />为了解决这个问题，我们可以为NetBeans设置自己的GEM_HOME，也就是它把gem安装到哪里。假设你是使用dmg安装的NetBeans，那么应该装在/Applications/NetBeans目录下，这样可以打开下面到文件。<br /><pre name="code" class="bash">
sudo vim /Applications/NetBeans/NetBeans\ 6.0.app/Contents/MacOS/netbeans
</pre><br />然后加入如下内容：<br /><pre name="code" class="bash">
export GEM_PATH=/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8:/Library/Ruby/Gems/1.8
export GEM_HOME=/Library/Ruby/Gems/1.8
</pre><br />注意一定要加到其他代码到前面，就可以了。<br /><br />从以上也可以看出，Leopard中gem的安装是有两个目录的。/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8这个是系统目录，是自带的gem；/Library/Ruby/Gems/1.8是非系统目录，是我们自己安装gem时到目录。例如rails-1.2.3就在前面到目录中，而我们自己安装rails-2.0.2的话，就在后面到目录里。<br /><br />这样看来就很清除了，我们告诉NetBeans到以上两个目录中找gem，而安装gem到非系统用户，就没问题了。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/156837#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jan 2008 10:57:41 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/156837</link>
        <guid>http://allenyoung.javaeye.com/blog/156837</guid>
      </item>
      <item>
        <title>在Leopard上手动安装RMagick</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/156831" style="color:red;">http://allenyoung.javaeye.com/blog/156831</a>&nbsp;
          发表时间: 2008年01月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这几天刚刚给自己的小白安装了Leopard，开始迫不及待的把开发环境搬到上面去。Leopard已经自带了完整的ruby-1.8.6和rails-1.2.3，我的项目是用rails-1.2.6的，另外还有一些gem要安装，所以二话不说，马上开始。<br /><pre name="code" class="bash">
# 更新gems，从0.9.4到1.0.1
sudo gem update --system
# 安装rails-1.2.6
sudo gem install rails -v 1.2.6
# 安装rails-2.0.2
sudo gem install rails
# 安装其他package
sudo gem install ferret
sudo gem install acts_as_ferret
sudo gem install mongrel
</pre><br />然后就到最重要到rmagick了。本来想通过macports来安装，但是速度实在太慢了，所以干脆自己来。把依赖的package都下载好，编译、安装，最后再sudo gem install rmagick，搞定。贴一段脚本上来，以后可以直接执行这段脚本来安装，省得麻烦。不过安装速度挺慢的，可能是我到小白性能不太好。脚本中用到到下载地址各位同学可以自己去换，比如有新版本或其他mirror更快到时候。<br /><pre name="code" class="bash">
#!/bin/sh

curl -O http://nchc.dl.sourceforge.net/sourceforge/freetype/freetype-2.3.5.tar.gz
tar xzvf freetype-2.3.5.tar.gz
cd freetype-2.3.5
./configure --prefix=/usr/local
make
sudo make install
cd ..

curl -O http://jaist.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.24.tar.gz
tar xzvf libpng-1.2.24.tar.gz
cd libpng-1.2.24
./configure --prefix=/usr/local
make
sudo make install
cd ..

curl -O ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz
tar xzvf jpegsrc.v6b.tar.gz
cd jpeg-6b
ln -s `which glibtool` ./libtool
export MACOSX_DEPLOYMENT_TARGET=10.5
./configure --enable-shared --prefix=/usr/local
make
sudo make install
cd ..

curl -O http://dl.maptools.org/dl/libtiff/tiff-3.8.2.tar.gz
tar xzvf tiff-3.8.2.tar.gz
cd tiff-3.8.2
./configure --prefix=/usr/local
make
sudo make install
cd ..

curl -O http://jaist.dl.sourceforge.net/sourceforge/wvware/libwmf-0.2.8.4.tar.gz
tar xzvf libwmf-0.2.8.4.tar.gz
cd libwmf-0.2.8.4
make clean
./configure
make
sudo make install
cd ..

curl -O http://www.littlecms.com/lcms-1.17.tar.gz
tar xzvf lcms-1.17.tar.gz
cd lcms-1.17
make clean
./configure
make
sudo make install
cd ..

curl -O http://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/gs861/ghostscript-8.61.tar.gz
tar zxvf ghostscript-8.61.tar.gz
cd ghostscript-8.61
./configure  --prefix=/usr/local
make
sudo make install
cd ..

curl -O ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/current/ghostscript-fonts-std-8.11.tar.gz
tar zxvf ghostscript-fonts-std-8.11.tar.gz
sudo mv fonts /usr/local/share/ghostscript

curl -O http://imagemagick.site2nd.org/imagemagick/ImageMagick-6.3.7-10.tar.gz
tar xzvf ImageMagick-6.3.7-10.tar.gz
cd ImageMagick-6.3.7
export CPPFLAGS=-I/usr/local/include
export LDFLAGS=-L/usr/local/lib
./configure --prefix=/usr/local --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8 --with-gs-font-dir=/usr/local/share/ghostscript/fonts
make
sudo make install
cd ..

sudo gem install rmagick
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/156831#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jan 2008 10:44:01 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/156831</link>
        <guid>http://allenyoung.javaeye.com/blog/156831</guid>
      </item>
      <item>
        <title>使用ruby生成zip文件</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/134858" style="color:red;">http://allenyoung.javaeye.com/blog/134858</a>&nbsp;
          发表时间: 2007年10月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          首先安装rubyzip：<br /><br />gem install rubyzip<br /><br />《Ruby Cookbook》里面简要地介绍了如何使用rubyzip读写zip文件，代码如下：<br /><pre name="code" class="ruby">
# 写zip
require 'rubygems'
require 'zip/zipfilesystem'

Zip::ZipFile.open('zipfile.zip', Zip::ZipFile::CREATE) do |zip|
  zip.file.open('file1', 'w') { |f| f &lt;&lt; 'This is file 1.' }
  zip.dir.mkdir('sub_dir')
  zip.file.open('sub_dir/file2', 'w') { |f| f &lt;&lt; 'This is file 2.' }
end
</pre><br />但实际上这段代码没什么用处，一般我们都是要把已有的文件或文件夹压缩成zip，要怎么办呢？基本想法是递归遍历给定文件（目录），然后把文件一个一个的加入zip文件中。代码如下：<br /><pre name="code" class="ruby">
def compress
  Zip::ZipFile.open 'zipfile.zip', Zip::ZipFile::CREATE do |zip|
    add_file_to_zip('dir', zip)
  end
end

def add_file_to_zip(file_path, zip)
  if File.directory?(file_path)
    Dir.foreach(file_path) do |sub_file_name|
      add_file_to_zip("#{file_path}/#{sub_file_name}", zip) unless sub_file_name == '.' or sub_file_name == '..'
    end
  else
    zip.add(file_path, file_path)
  end
end
</pre><br />其实最主要的就是ZipFile类的add方法，第一个参数指定zip文件中的路径，第二个参数指定要被压缩的文件的路径。<br /><br />另外还要注意的是Dir.foreach会返回指定目录中的所有子文件（目录），包括"."和".."，所以要做额外的判断。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/134858#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 23 Oct 2007 17:28:28 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/134858</link>
        <guid>http://allenyoung.javaeye.com/blog/134858</guid>
      </item>
      <item>
        <title>关于苹果的老总、苹果的粉丝和苹果的产品</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/133964" style="color:red;">http://allenyoung.javaeye.com/blog/133964</a>&nbsp;
          发表时间: 2007年10月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Ok，我知道，这里更应该写技术博客，我在这里说这些无聊的话没什么意思，但是这几天老罗好像心血来潮似的连续发表关于苹果的言论，字里行间都透露着一种让人不舒服的得意心理。那种感觉就好像全世界只有他看清了事实的真相、其它人都是笨蛋一样。虽然老罗一贯是这样的口吻（我没敢说嘴脸，呵呵），但是这次着实让我不爽，因为关于苹果的事情怎么看都是比较专业的话题，老罗虽然自称卖过电脑（好像是在天津吧），但是也不会专业到精辟点评苹果的程度。<br />
<br />
老罗已经写下了苹果的老总、苹果的粉丝，还要打算写苹果的产品。趁他还没写出来，我在这里说说自己的想法，权当自娱自乐。我知道，我知道，这里更应该写技术博客，但是我也比较为难，因为已经把博客开到这里了，总不能想说些什么都不可以吧？所以把这篇博客看作赚人眼球的无聊玩意儿的人，请你们原谅我，我不是存心要污染你们的视觉的。<br />
<h3>关于苹果的老总</h3>
乔布斯到底是个什么样的人，估计我们都不了解。人们认识他是从他一次一次地推出新的产品、一次一次地亲自主持Mac World和WWDC，还有更为人津津乐道的在斯坦福大学毕业典礼上的演讲。老罗看了乔布斯的传记，一一列举了他的缺点：蛮横霸道、好大喜功、剽窃他人研究成果、等等等等，并无不讽刺的引用说&ldquo;我们应该允许我们的英雄出现一些过错。没有过错的英雄是不会获得成功的。然而，在最后，我们应该记住的不是他的过错，而是他做出的贡献。&rdquo;在这里很让我奇怪的一点是老罗似乎专门拿乔布斯的坏处说事儿，这样一来只能把他的这篇博客定义为&ldquo;反苹果&rdquo;的基调。如果有了这样的基调，那么对事实的描述自然有不准确之嫌。这里我想说说我所知道的乔布斯。<br />
<br />
首先，我承认，老罗列举出来的乔布斯的总总罪状都是事实，我也无意反驳他，说这些都是假的，或者更恶心的说这些恰恰是乔布斯的过人之处，我只是想让大家看看一个更完整的乔布斯。<br />
<br />
乔布斯的生父生母都是收过高等教育的人，但是生下乔布斯的时候，他们还是大学生，而且用乔布斯自己的话说，他们想要的是个女孩，所以乔布斯是个&ldquo;unwanted child&rdquo;。后来他们把乔布斯送给了一户工人家庭，条件是要保证将来乔布斯能有上大学的机会。乔布斯就是这样开始了他的人生，一个意料之外的孩子。<br />
<br />
之后他去了大学，但是不喜欢自己的专业，于是退了学，却仍然留在学校里去听一些别人看来没有意义的课，其中有一门是讲字体的（当然是手写字的字体，书法）。乔布斯说正是这些课程，给了他无穷无尽的财富。后来，他和沃兹尼亚克在车库里创建了苹果。再后来，苹果发达了。我得承认，苹果的早期成功，绝大部分的功劳应该属于沃兹尼亚克，正式这个百年难得一见的天才从硬件到软件全部自己动手，一点一点的大早了早期苹果的拳头产品。而且沃兹尼亚克的为人是非常好的，当初乔布斯占有苹果70%的股份，沃兹尼亚克30%，而其它员工没有股份。沃兹尼亚克劝说乔布斯拿出一部分股份分给员工，乔布斯不同意，于是沃兹尼亚克把自己30%个股份无私地分给了员工。后来由于种种原因，沃兹尼亚克离开了苹果，但是他对苹果的认同还是没有改变的。这一点我们可以从两个方面看出：<br />
<ol>
    <li>沃兹尼亚克的自传叫《iWoz》，秉承了苹果一贯的产品命名方式。</li>
    <li>前阵子iPhone在美国刚刚上市的时候，沃兹尼亚克也排队去购买，有一张他做在Apple Store的沙发上等待的照片，很是耐人寻味。</li>
</ol>
顺便一提，天才往往都不会有一个完满的结局。可怜的沃兹尼亚克得了严重的类似健忘症的疾病，现在只能在小学里面叫小学生使用电脑，真是遗憾。我们可能再也看不到一个人单枪匹马搞出一台电脑的壮举了。<br />
<br />
老罗列举出了乔布斯在苹果是的种种恶行，但是奇怪的是，这样一个可恶的家伙，再被苹果扫地出门后，苹果的业绩竟然一落千丈，而乔布斯此时正在率领新创建的一个动画工作室逐渐成为全美甚至全世界最好的动画工作室之一。多年以后，当乔布斯再次回到苹果时，世界上多了一个大名鼎鼎的名字：Pixar。让我们看看它制作的动画电影：《Toy Story》、《A Bug's Life》、《Monsters Inc.》、《Finding Nemo》、《The Incredibles》、《Cars》、《Ratatouille》，哪一部不是大名鼎鼎？Pixar开发的RenderMan一直被图形学界认为是最强大的实时渲染语言。而现在，我们都知道，乔布斯更是凭借Pixar成为了迪斯尼的股东。多么的奇妙。顺便一提，Pixar公司的工作环境真是太high了，那是一个比Google更奇妙的地方。<br />
<br />
以上事实是无法让人理解的，这么一个恶人，却自己不断的成功，而苹果在离开了他之后，即便找来了当时百事可乐的CEO来撑门面，不过还是节节败退。之后乔布斯又回到了苹果，并推出了一系列产品：<br />
<ol>
    <li>Mac系列台式电脑（笔记本），还记得那个360度旋转的屏幕吗？还记得经典的贝壳吗？</li>
    <li>Mac OS X Tiger，可能是目前最好的操作系统（当然Leapard马上就要出来了）。</li>
    <li>iPod，彻底改变了MP3市场，甚至人们听音乐的习惯。</li>
    <li>iTunes，彻底改变了美国和一些其它国家的音乐消费市场。</li>
    <li>iPhone，这个还用说吗？哪个人在第一次看乔布斯演示iPhone的时候没有cool的感觉呢？</li>
</ol>
我们不禁要问，这是为什么呢？我说不清楚，乔布斯是有很多的缺点，也有不太光彩的历史，但是似乎苹果不适合由一个卖汽水的人来掌舵。<br />
<br />
让我们再来看看微软和盖茨，这个总被人拿来与苹果比较的公司和他的老板。近几年，人们对微软和盖茨的好感是大有增加，原因好像只有一个，盖茨成了慈善家。我得承认，盖茨算是个善人，他把自己几乎所有的财产都捐献给了慈善机构。但是盖茨不仅仅是这几年的盖茨，我们要整体的看。<br />
<br />
那么我们了解盖茨多少呢？也不多，因此没有发言权。不过我想引用朱敏先生的一些言论&ldquo;他说盖茨的文化是掠夺的文化，你有比他好的东西，千万别让他看见，看见了他就复制你，然后靠财大气粗打垮你。不过盖茨近几年变得好多了，我想是因为他有了小孩。你想想看自己的小孩被人家打垮是什么感觉？&rdquo;<br />
<br />
好了，说了这么多，差不多该结束这一段了。最后顺便说一句，乔布斯得过癌症，不过痊愈了，现在还能活蹦乱跳的确实不太容易。<br />
<h3>关于苹果的粉丝</h3>
首先我想说明一下，拿苹果用户的IQ说事儿完全没有必要，而且显得很低级，喜欢一个产品与IQ有啥关系。<br />
<br />
苹果走的并不是大众路线，因此培养一批铁杆粉丝在战略上是绝对必要的，在这一点上苹果和乔布斯是正确的，没有什么愚民、洗脑的问题。我们生活在这样一个世界，绝大多数的信息都是别人告诉你的，你要有选择的相信，人家说的也不是什么言不符实的话，哪来的那么严重？<br />
<br />
现在的人们好像总是喜欢各种方式的思维和批评，因此无论出现个什么东西，都会有粉丝，然后马上就会出现&ldquo;某某盲从者&rdquo;的字眼。这似乎成了一个定势，但是只要这确实是我喜欢的东西，还怕什么呢？有那么多男男女女喜欢李宇春、好男儿，有如何呢？<br />
<br />
老罗总是把apple snob这个词放在嘴边，我也承认确实没有microsoft snob这次词。但是snob就snob呗，这只是一种态度、一种方式，有怎么样呢？就花了冤枉钱、就傻瓜了吗？我不这么认为，这个在关于苹果的产品里再说。<br />
<br />
我本身是一个苹果的用户，用着iBook和iPod，身边也有一些喜欢并使用苹果产品的朋友，姑且都叫粉丝吧。奇怪的是，这些粉丝都没有老罗说的那么死硬、那么无药可就。因此，请不要总拿死硬派说事儿，请看看实际情况再说，不然比较无聊。<br />
<br />
算了，我想在这个段落里面还是少说点儿吧。这毕竟是要说到人的，我可不想不负责任的对别人评头论足。<br />
<h3>关于苹果的产品</h3>
苹果究竟都有哪些产品呢？电脑、操作系统、MP3播放器、手机、应用软件，还有一些附加硬件设备。那么就让我们一个一个的看一下。<br />
<h4>电脑和操作系统</h4>
首先要声明一点，苹果的电脑绝对不满，特别是和微软的东西比起来。老罗说他的苹果电脑慢，那只能说明你用的不对。我的iBook配置比较低了，PowerPC G4 1.2MHz、768M SDRAM，30G 4200转串口硬盘。但是和我的IBM T42（装正版Windows XP SP2）比起来，无论是开关机速度，还是启动应用程序的速度，那都是无法比的（我的很多朋友也都是同样的感觉）。如果老罗的苹果电脑，一切操作都很正常，那么就只能归咎于RP问题了。<br />
<br />
苹果之前一直用的是PowerPC的架构，这个东西是IBM和Motolora搞出来的。这个平台比intel的x86最大的好处不是精简指令集，而是它对长浮点数的运算有特别的优化。具体来说就是，它在汇编基本加入了对长浮点数的分段计算指令。比如你有一个512位的浮点数运算，PowerPC可以把它拆成8个64位的运算，然后合并。这就是为什么老苹果上做图形处理性能更佳的原因，当然我只的是同样的cpu主板配置的情况下。<br />
<br />
苹果为什么要转向intel？让我们来看看当时的情况，intel已经推出了双核，而仅仅迅驰2代的频率也达到了很高的程度，外加2M的二级缓存。而PowerPC当时的配置呢？cpu频率跟不上市场走势，而且二级缓存才有可怜的256K。这可以说是PowerPC架构的发展遇到了瓶颈，而不是苹果选择平台的问题。因为在相同配置的情况下，PowerPC更适合做图形运算。而PowerPC有什么问题呢？问题不在性能上，它可以做出搞性能的cpu，问题在发热度上。它太热了，以至于无法有效的散热。因此苹果转向了intel，这有什么可说的呢？而苹果的操作系统在一开始的时候就过着&ldquo;secret double life&rdquo;，这正是苹果的高明之处，为自己留了后路。至于为什么最开始的时候不允许intel平台装Mac OS呢？这就是战略和定位了。<br />
<br />
在看看苹果的操作系统。Mac OS是基于Unix的，这保证了它的核是可靠的、高效的。Mac上出现的各种病毒总共不过几百个，看看Windows呢？我的iBook买回来快3年了，从来没有因为客观原因重装过系统，Windows呢？至于用户体验方面，我想就不必多说了。很多人都说Mac不好用，我说是他们用惯了Windows，如果你坚持用Mac一个月，我保证会改变你的看法。<br />
<br />
当然Mac也有缺点，我个人感觉比较严重的就是它比较封闭，不利于扩展。但这也主要是因为现在Windows垄断了PC市场，仔细想想的话，Windows更封闭。这种拿出去卖钱的操作系统，不可能真正的开发、灵活。<br />
<br />
顺便说一个小故事。Mac上开发程序主要是用cocoa，苹果有自己的开发工具Xcode，当然还有很多第三方的开发工具。苹果的Mac OS在发布的6年之后才宣布自己一直都支持intel平台，而且Xcode可以吧cocoa程序编译成两个平台通吃的universal binary，这样一来估计其它的工具就都要走麦城了。<br />
<h4>应用软件</h4>
这个就不用多说了吧，iLife和iWork足以让所有同类型的Windows应用程序汗颜。比较一下Keynote和PowerPoint就知道了。另外还有很多专业的图像、视频、音频制作软件。就更不用说了，迪斯尼的电影尤其制作多是由这些软件完成的。<br />
<h4>MP3播放器</h4>
啊，iPod，我们甚至可以说iPod改变了这个世界。它容易挂花又怎么样呢？指纹收集器有怎么样呢？这都不妨碍它成为MP3市场播放器的霸主。是所有人都疯了吗？话说回来，有哪个电子产品不会被挂花呢？<br />
<h4>手机</h4>
我不知道现在能不能把iPhone说成一场革命，但它至少已经成为了一种现象。我也不知道它最终是否会大获成功，但是它为所有的手机厂商树立了一道标尺，这才是最重要的。<br />
<h4>附加硬件设备</h4>
苹果的附加硬件设备确实贵，这个没什么可说的。我也希望它便宜下来。不过抛开这些设备不谈，苹果的主打产品其实都不算贵。<br />
<ol>
    <li>看看现在的苹果电脑，无论是台式机还是笔记本，基本和同配置的IBM、HP、Sony之类的差不多。当然如果你非要和神舟之类的做比较，我也没办法，我只能说那确实还是贵的。</li>
    <li>苹果的操作系统和应用软件远比微软的便宜得多。</li>
    <li>iPod可能相对贵一些，但是它是在MP3市场上无人可以出其二的产品。</li>
    <li>iPhone在美国的价格大概也就和Nokia N70刚上市时差不多。</li>
</ol>
以上是苹果的产品，那么微软呢？这么多年微热只做了一件事，用Windows垄断了PC，然后借着这个有时垄断了Office系列软件。这是它的成就，我没有任何怀疑与不屑。<br />
<br />
盖茨支持了慈善事业，大家对他的态度马上就有了720度的大转变。但是想想他从大家身上赚了多少钱呢？哦，对了，中国人一般都用盗版，所以没感觉。苹果现在好像没在慈善事业上有多少曝光率，但是看看它对客户是怎么做的：iPhone的老用户返还100美元购物抵用券；新买苹果电脑的用户，购买Leapard时大幅度优惠。这种对社会的回馈也不是小举动，为什么在微软身上就看不见呢？更奇怪的是，为什么大家都视而不见呢？<br />
<br />
我不是苹果的死硬粉丝。但是如果让我选一个人作为IT界非技术类的偶像，乔布斯是我不二的选择。是的，他有很多缺点，有的甚至不能让人忍受。但是如果在三国人物中选一个人出来佩服的话，我还是会选曹操，道理是一样的。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/133964#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 21 Oct 2007 12:52:33 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/133964</link>
        <guid>http://allenyoung.javaeye.com/blog/133964</guid>
      </item>
      <item>
        <title>在habtm上使用polymorphic关联</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/129195" style="color:red;">http://allenyoung.javaeye.com/blog/129195</a>&nbsp;
          发表时间: 2007年10月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我们知道，在rails中，habtm和polymorphic都是非常好的东东，特别是后者，可以说是rails的ORM中非常强大的功能。《Agile Web Development with Rails》虽然详细讲述了habtm和polymorphic关联，也讲了如何把模型类映射为连接表，但是并没有讲如何把habtm和polymorphic一起使用做一个介绍。这里我就来简单说一下。<br /><br />还是出自真实项目中的需求，项目是全国大学本科教学评估支持系统，说白了就是大学用来支持本科教学评估的东西。里面有这样一个use case：<br /><br />评估中需要召开座谈会，参加的人有：专家、教师、学生...（反正就是学校里面的各色人等），并且参加座谈会的各种人都可以是多个。这样就有了这样一个多对多的数据关系：多个人可以参加多个座谈会，参加者的类别是不一样的（需要polymorphic）。<br /><br />让我们仔细看看这个use case，其实它还是挺微妙有趣的。如果不考虑polymorphic，那么这里显然就是一个标准的habtm关系，那么我们就建立三张表users、symposia和symposia_users，然后两边用habtm关联一下就好了。<br /><br />但是如果要考虑polymorphic，就没有这么简单了。这里最主要的问题是habtm本身不支持polymorphic选项，支持polymorphic选项的只有belongs_to。那么我们就不得不把habtm拆成has_many和belongs_to两部分了。<br /><br />先创建关联表attendances及其响应的model：<br /><pre name="code" class="ruby">
# create_attendances.rb--------------------------------------
create_table :attendances do |t|
  t.column :attendee_id,   :integer
  t.column :attendee_type, :string
  t.column :symposium_id,  :integer
end
# attendance.rb----------------------------------------------
class Attendance &lt; ActiveRecord::Base
  belongs_to :attendee, :polymorphic => true
  belongs_to :symposium
end
</pre><br />其中的attendee就会多态地关联到专家、教师、学生等人员身上。<br /><br />然后再配置symposium.rb、expert.rb、teacher.rb、student.rb：<br /><pre name="code" class="ruby">
# symposium.rb------------------------------------------------
class Symposium &lt; ActiveRecord::Base
  has_many :attendances
  has_many :experts,
           :through => :attendances,
           <strong>:source => :attendee,
           :source_type => 'Expert'</strong>
  has_many :teachers,
           :through => :attendances,
           :source => :attendee,
           :source_type => 'Teacher'
  has_many :students,
           :through => :attendances,
           :source => :attendee,
           :source_type => 'Student'
end
# teacher.rb--------------------------------------------------
class Teacher &lt; ActiveRecord::Base
  has_many :attendances, :as => :attendee
  has_many :symposia, :through => :attendances
end
# expert.rb和student.rb与teacher.rb相同------------------------
</pre><br />以上代码都比较好理解，就是其中的source和source_type选项可能不是很常见，看看ActiveRecord的doc就会明白，source用来指定关联到attendance的哪个属性上（当然就是attendee），而source_type则是在使用了polymorphic的情况下指定attendee的具体类型。<br /><br />经过以上的配置，整个model的关系就建立起来了，不过在使用这些关系的时候仍需注意一点。假设我们要新建一个座谈会，参与者有专家1、2，教师1、2和学生1、2，代码要怎么写呢？很多人可能都会想是：<br /><pre name="code" class="ruby">
symposium = Symposium.new(:name => "座谈会1")
symposium.experts &lt;&lt; Expert.find(1) &lt;&lt; Expert.find(2)
symposium.teachers &lt;&lt; Teacher.find(1) &lt;&lt; Teacher.find(2)
symposium.students &lt;&lt; Student.find(1) &lt;&lt; Student.find(2)
symposium.save
</pre><br />不过这样写是不对的，会得到如下错误：<br /><br />ActiveRecord::HasManyThroughCantAssociateNewRecords: Cannot associate new records through 'Symposium#attendances' on '#'. Both records must  have an id in order to create the has_many :through record associating them.<br /><br />意思是说symposium和teacher（expert、student）之间的关联要通过attendance，而现在还没有attendance呢（即both records must have an id）。那么要如何先把要用的attendance创建出来呢？对，在建立关系前先创建并保存symposium，这样就间接地提前创建了需要用的attendance。<br /><pre name="code" class="ruby">
begin
  Symposium.transaction do
    symposium = Symposium.new(:name => "座谈会1")
    symposium.save!    <strong># 这句很重要</strong>
    symposium.experts &lt;&lt; Expert.find(1) &lt;&lt; Expert.find(2)
    symposium.teachers &lt;&lt; Teacher.find(1) &lt;&lt; Teacher.find(2)
    symposium.students &lt;&lt; Student.find(1) &lt;&lt; Student.find(2)
    symposium.save!
  end
rescue
  # 处理事务中的异常...
end
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/129195#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 05 Oct 2007 15:19:02 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/129195</link>
        <guid>http://allenyoung.javaeye.com/blog/129195</guid>
      </item>
      <item>
        <title>尝试在rails中调用MySql的stored procedure，不过最终放弃了。</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/128979" style="color:red;">http://allenyoung.javaeye.com/blog/128979</a>&nbsp;
          发表时间: 2007年10月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          手头一个项目有这样一个需求，数据库中有一张学生表students，其中每个学生都有自己的生源地(come_from)，用户希望能够随机的选择一些学生出来，但是要保证每个生源地的学生都有。<br /><br />我的开发环境是RoR + MySql，简单考虑了一下后，第一个能想到的方法是在rails中生成随机数，然后用offset来得到随机的学生。但是这样做比较麻烦，性能也会很差，因为首先要知道每个生源地下有多少学生，不然的话，生成的随机数可能会过大。<br /><br />排除了这个选择，于是考虑是否可以在sql级别实现。去查了查MySql的manual，发现有个然数RAND()可以用来生成0到1之间的随机浮点数，感觉可以用这个来做，马上试试看。<br /><pre name="code" class="sql">
SELECT * FROM students WHERE come_from = '上海市' ORDER BY RAND() LIMIT 1;
</pre><br />注意，这里的随机方式与一般的想法不同。一般的想法是生成一个随机数作为offset，然后去找在offset上的数据项；而这里的做法是随机的对数据项进行排序（即shuffle），然后获得第一个。<br /><br />以上sql多运行了几次下来，确实随机返回不同的学生，离目标近了一步，好事情。剩下来就是如何随机的在所有生源地上选择一个学生，如果学生个数不够，还要再随机选择剩余学生。出于性能考虑，我打算用stored procedure：<br /><pre name="code" class="sql">
CREATE DEFINER=`root`@`%` PROCEDURE `random_students`()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE var_come_from VARCHAR(255);
  DECLARE come_from_cursor CURSOR FOR SELECT come_from FROM eva_development.students GROUP BY come_from;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

  OPEN come_from_cursor;

  REPEAT
    FETCH come_from_cursor INTO var_come_from;
    SELECT * FROM eva_development.students where come_from = var_come_from order by rand() limit 1;
  UNTIL done END REPEAT;

  CLOSE come_from_cursor;
END
</pre><br />以上代码还是挺简单的，就是先找到所有的生源地，然后循环，以每个生源地作为条件随机出一个学生来。一开始的时候我还想传入一个参数，代表想要得到的学生个数，比如50、100的。因为这个个数通常比生源地个数要多，所以后面还应该随机取出一些学生来。但是我不知道这个sql应该怎么写，因为假设我们可以得到变量student_number代表想要的学生个数、come_from_number代表生源地的个数，那么sql语句应该差不多如下：<br /><pre name="code" class="sql">
SELECT * FROM students LIMIT <strong>(student_number - come_from_number)</strong>;
</pre><br />但是其中加粗的部分，sql自然是不认识的，也就是说LIMIT后面不能接变量，所以我也不知道该怎么办，所幸就拿到stored procedure外面来做了。<br /><br />以上可以说是实现了MySql端的东东，那么rails方面呢？一开始我尝试使用<br /><pre name="code" class="ruby">
Student.find_by_sql('call random_students()')
</pre><br />结果报错说：ActiveRecord::StatementInvalid: Mysql::Error: PROCEDURE vc.testsp can’t return a result set in the given context.<br /><br />到网上搜了一下，发现rails的wiki里面就有一篇讲怎么使用sp的，于是就按部就班的做了，不过网上的教程有点儿过时了，这里稍微做一个介绍：<br /><ol><li>先保证自己装的是MySql 5.0+版本。</li><li>安装native MySql Connector：gem install mysql。</li><li>修改rails中的mysql_adapter.rb，文件在$RUBY_ROOT/lib/ruby/gems/1.8/gems/activerecord-$VERSION/lib/active_record/connection_adapters中，具体修改如下：</li><pre name="code" class="ruby">
ConnectionAdapters::MysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket], config)
</pre><br />==><br /><pre name="code" class="java">
ConnectionAdapters::MysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket, 65536], config)
</pre><br />这是因为sp有可能会返回多个结果集（说白了就是有多个SELECT，像我的sp就是这样），而rails默认的连接设置不支持这个，就会报错，而且即使只返回一个结果集，也会报一样的错误。65536代表的是MySql选项CLIENT_MULTI_STATEMENTS，这样一来就知道怎么回事儿了。<li>为rails添加一个调用sp的方法：</li><pre name="code" class="ruby">
def select_sp(sql, name = nil)
  rows = select(sql, name = nil)
  while (@connection.more_results?())
    @connection.next_result()
  end        
  return rows
end
</pre><br />这个方法应该添加在ConnectionAdapters::MysqlColumn中（仍然在mysql_adapter.rb中），可以加到SCHEMA STATEMENTS段。<li>最后在Student.rb里面加入调用sp的方法：</li><pre name="code" class="ruby">
def self.random_select(student_number)
  students = connection.select_sp('call random_students')
  students &lt;&lt; find_by_sql(['select * from students order by rand() limit ?', student_number - students.length]) unless students.length >= student_number
  students.flatten[0, student_number]
end
</pre><br /></ol><br />写了这么多，以为可以万事大吉了，谁知道调用下来，却报了下面这个错误：Commands out of sync; you can't run this command now.这下可不知道怎么办了，搜了一阵子也没有答案。我猜想可能与多结果集有关，于是写了一个单结果集的sp来调用，果然就没有问题。看来我的这个功能还真不能在sql里面做咧，于是只好全部转到ruby里面，不过还好有MySql的RAND()函数，性能不是太差，而且我数据库里面大概就2w数据，不多。<br /><pre name="code" class="ruby">
def self.random_select(number = 50)
  result = []
  students = Student.find_by_sql('select come_from from students group by come_from')
  students.each do |student|
    result &lt;&lt; Student.find_by_sql(['select * from students where come_from = ? order by rand() limit 1', student.come_from])
  end
  result &lt;&lt; Student.find_by_sql(['select * from students order by rand() limit ?', number - students.length]) unless students.length >= number
  result.flatten[0, number]
  end
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/128979#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 03 Oct 2007 17:00:27 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/128979</link>
        <guid>http://allenyoung.javaeye.com/blog/128979</guid>
      </item>
      <item>
        <title>我的第一关rake文件</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/126309" style="color:red;">http://allenyoung.javaeye.com/blog/126309</a>&nbsp;
          发表时间: 2007年09月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          早就想找个机会写写rake文件，但是接触到的项目都不怎么需要，所以一直也没有去学习一下。这两天一个项目需要把客户给的很多excel文件导入到数据库中（我用的好似MySQL），到网上找了一些工具，感觉都不好，因为客户的excel格式比较乱（特别是日期的格式，竟然是中文数字和阿拉伯数字都有的...），所以就想干脆仔细写一个算了。这是正好想到可以顺便学习一下rake，于是就动手啦。<br /><br />网上关于rake的文章有不少。如果想快速上手，那么Rails Envy的<a href="http://www.railsenvy.com/2007/6/11/ruby-on-rails-rake-tutorial#rails_models" target="_blank">Ruby on Rails Rake Tutorial</a>是绝佳的入门教程；如果想从更高的角度理解rake，那么当然要看Martin Fowler大大的<a href="http://martinfowler.com/articles/rake.html" target="_blank">Using the Rake Build Language</a>了。<br /><br />好了，看完了入门教程，开始动手！先去看看rails项目根目录下的Rakefile这个文件，里面就是require了一大堆东西，没什么意思，有用的反而是文件开头的注释：<br /><pre name="code" class="ruby">
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
</pre><br />明白了吧，把rake文件写成.rake扩展名的，然后放到lib/tasks下面，rails就可以自动加载你的rake文件了。于是到lib/tasks下面创建我的文件data.rake：<br /><pre name="code" class="ruby">
require "lib/data_importer.rb"

namespace :eva do
  desc 'Import init data from csv files.'
  task :import_data => :environment do
    DataImporter.import_teachers
  end
end
</pre><br />以上代码非常容易理解，这也多亏了ruby强大的DSL能力。我就是创建了一个名为import_data的任务，然后在这个任务里面调用我自己写的DataImporter中的方法把excel中的数据导入到数据库中。<br /><br />namespace用来为任务创建一个名字空间，这样我写的import_data任务就是eva:import_data，别人也可以在其它名字空间下创建相同名字的任务。rake db:migrate中的db就是这么个名字空间。<br /><br />而:import_data => :environment这里声明了任务间的依赖关系，也就是import_data依赖于enviroment。那么enviroment是什么呢？执行一下rake --tasks查看所有的rake任务，没有叫这个名字的任务啊。怎么回事儿呢？其实你可以在RUBY_ROOT/lib/ruby/gems/1.8/gems/rails-&lt;version>/lib/tasks下面找到一个rails自带的所有rake文件，打开其中的misc.rake，内容如下：<br /><pre name="code" class="ruby">
task :default => :test
task :environment do
  require(File.join(RAILS_ROOT, 'config', 'environment'))
end
</pre><br />那么environment任务实际上是把当前rails项目的整个环境加载进来，这样就可以使用model啊、ActionSupport啊之类的东西了。<br /><br />那么为什么这个任务在rake --tasks中没有显示呢？那是因为这个任务没有响应的描述（可以理解为注释）。看看misc.rake和我的rake文件的区别就能发现，我的rake文件在任务前面有一行desc语句，它用来描述任务是做什么的，只有加了描述的任务才会在rake --tasks产生的列表中出现。<br /><br />有人可能会问，这不是很让人迷惑吗？可以显示这些任务，同时描述部分显示为空就好了啊。其实不然，从逻辑上看，不加desc的task应该是程序内部使用的，不应该被其它人使用，例如environment这个task，用来加载rails环境，如果显示在rake --tasks中，万一被别人滥用了，就不好了，所以最好不要显示，干脆让别人不知道有这个东东。这样一来，意在让别人使用的task可以加desc，不想让别人使用的task不加desc（可以加单纯的注释），岂不是两全其美？
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/126309#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 23 Sep 2007 17:10:06 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/126309</link>
        <guid>http://allenyoung.javaeye.com/blog/126309</guid>
      </item>
      <item>
        <title>修改DataGrid得默认scroll行为</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/124756" style="color:red;">http://allenyoung.javaeye.com/blog/124756</a>&nbsp;
          发表时间: 2007年09月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          用过Ext的人也许都会注意到，DataGrid的scroll行为只在当前DataGrid中有效。比如，一个带有纵向滚动条的DataGrid，如果我们把鼠标停留在DataGrid上并滚动滚轴，DataGrid中的条目就会随之滚动起来，一直到最后一条为止。这个时候，如果继续滚动，则不会有任何响应。整个网页也不会跟着滚动。在很多情况下，这样做是正确的，其目的是防止整个网页的滚动。因为当在DataGrid中滚动到最后一行时，用户很可能不希望整个网页随着鼠标滚轴滚动。<br /><br />但是在有些情况下这一行为并不适用。例如在我的一个项目中，页面上并不会指定DataGrid的高度，而是让数据自动把整个DataGrid撑起来，这样的话，DataGrid上就不会出现滚动条。而这个DataGrid占据着页面上较大的一部分，用户的鼠标通常会停留在DataGrid上进行滚动，其目的实际上是滚动整个网页。这个时候，如果不改变Ext的默认行为，网页就不会滚动，这种用户体验就是错误的。<br /><br />去看看Ext的文档，并没有这方面相关的说明，看来Ext本身并没有提供这样一个选项可以设置DataGrid的scroll行为。看来只能自己研究一下了。还好自己多少也和Ext打了些交道，估计这部分可能在Grid或GridView这两个文件中。分别去看这两个东东的源代码，感觉Grid不像，先暂时排除，然后去GridView里面找，发现有一个handleWheel函数，八成就是这个了，其代码是<br /><pre name="code" class="java">
handleWheel: function(e) {
    var d = e.getWheelDelta();
    this.scroller.dom.scrollTop -= d * 22;
    // set this here to prevent jumpy scrolling on large tables
    this.lockedBody.dom.scrollTop = this.mainBody.dom.scrollTop = this.scroller.dom.scrollTop;
    e.stopEvent();
}
</pre><br />看不懂的代码咱就不说了，关键是这里有个e.stopEvent()调用，就是它把页面的鼠标滚动事件吞了下去。那么去掉这个东东就好了。<br /><pre name="code" class="java">
Ext.override(Ext.grid.GridView, {
    handleWheel: function(e) {
        var d = e.getWheelDelta();
        this.scroller.dom.scrollTop -= d * 22;
        // set this here to prevent jumpy scrolling on large tables
        this.lockedBody.dom.scrollTop = this.mainBody.dom.scrollTop = this.scroller.dom.scrollTop;
    }
});
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/124756#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 17 Sep 2007 15:41:19 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/124756</link>
        <guid>http://allenyoung.javaeye.com/blog/124756</guid>
      </item>
      <item>
        <title>ferret啊，为你欢喜为你忧。</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/110587" style="color:red;">http://allenyoung.javaeye.com/blog/110587</a>&nbsp;
          发表时间: 2007年08月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          非常非常奇怪的问题。一开始在mac下面用standard rails bundle + ferret/acts_as_ferret，一切正常。后来想引入rmagick，于是使用rmagick bundle + ferrect/acts_as_ferret，结果报错，server启动不起来。mail list上去问，没人搭理咱。<br /><br />索性换到windows上，顺便开始测试网页的浏览器兼容性。把代码commit到svn，然后找台新装的windows xp sp2，安装ruby、rails、ferret、rmagick，然后checkout代码。启动server，报错说no such file to load -- acts_as_ferret (MissingSourceFile)，但是acts_as_ferret分明就在vender/plugins下面。而且同一个team里面有的人有这个问题，有的人就没有。<br /><br />我这里是把acts_as_ferret作为plugin安装的。原因么，一是觉得plugin可以随着project一起checkin到svn中，大家可以共享；二是因为我在开始使用ferret的时候，acts_as_ferret的gem安装是0.10版本（非常奇怪）。现在报着最后的希望把acts_as_ferret安装成gem，这次还不错，找到了0.41版本。然后启动server试试，一切正常了。<br /><br />非常的不解，看上去安装成gem比安装成plugin更保险一些，可是为什么之后acts_as_ferret有这种问题？<br /><br />另外顺带提一下ferret的中文分词器，前一阵子尝试去实现一个，找了一个java版的作为研究对象，得出的结论是很难。java里面把读进的每个字符都做了统一的处理，我可以很简单的知道一个document中那些是一个character。而c中就没这么简单了，如果编码是utf-8，那么一个中英文混合加阿拉伯数字的document中的character就是不定长的，就不知道从哪里断开了。而且据说有些c编译器处理宽字符还有问题。<br /><br />唉，我不是c的高手，对字符集这个东西也没有研究。希望我上面的说法是错误的，不然真的很难写一个c的中文分词器咧～
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/110587#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 09 Aug 2007 18:05:33 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/110587</link>
        <guid>http://allenyoung.javaeye.com/blog/110587</guid>
      </item>
      <item>
        <title>在Mac上安装RMagick？别以为有了Locomotive就万事大吉啦～</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/108095" style="color:red;">http://allenyoung.javaeye.com/blog/108095</a>&nbsp;
          发表时间: 2007年08月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我或多或少算是一个Mac fan，但是对于这件事，我不得不说自己还是有一些失望的。在Mac上做开发已经有一段时间了，整体感觉就是Mac对developer的支持不是很好。也许Mac的目标主要就是家庭用户，但是作为Mac fan兼，当然是希望它能适合我么developer的口味。<br /><br />这次的问题是在Mac上安装RMagick，网上有很多文章详细说明了如何手动安装，我这里就不重复了，而且手动安装也问题多多。因为有了Locomotive这个好东西，简化了很多安装的过程。最简单的办法就是到Locomotive的主页上下载一个含有RMagick的bundle，按道理说就万事大吉了，不是吗？<br /><br />实际情况是，不是。安装好RMagick的bundle后，在Locomotive中启动server，一切正常，访问http://localhost:3000，浏览器说找不到服务器，为啥呢？赶紧到命令行下面去看看，执行./script/server，报错，哦，原来server并没有真正被启动。<br /><br />貌似在Locomotive中启动server永远是“成功”的，其实server并没有启动，但是Locomotive显示的还是已启动，启不是很奇怪？这个应该算是Locomotive一个不完善的地方吧？还是我使用的方式不对？<br /><br />然后再来看看server报出的错误信息，大概意思是RMagick找不到/usr/X11R6下面的什么东东。看样子是RMagick要用到X11，而我的Mac没有安装。OK，找来安装一下应该就可以了吧。于是就到apple官网上下载了X11和一个update文件，结果安装时系统确提示说已经安装过了更新版本的X11，不能安装现在的文件。真是奇怪，spotlight一下，发现确实有几个目录名为X11R6或X11。一路找下去，发现这些文件都位于/Developers/SDKs下面的一些目录中。我这才明白，这些东西是之前在安装xcode时安装上来的。<br /><br />这个大概就是Mac的问题了，为什么要把X11（还有很多类unix系统常用的东东）安装到这么奇怪的目录下呢？Mac的根是unix，虽然为了商业考虑是要做一些改变，但是一些已成共识的东西最好还是保留为好吧？<br /><br />到apple官网上搜了一下，发现Tiger安装盘里面附带了X11，可以选装。晚上回家试了一下，结果从安装盘里安装X11就很顺利，确实也安装到了/usr下面，启动一下server，一切都没问题，算是解决了。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/108095#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 02 Aug 2007 09:30:48 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/108095</link>
        <guid>http://allenyoung.javaeye.com/blog/108095</guid>
      </item>
      <item>
        <title>在controller里面怎么escape html内容？</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/104662" style="color:red;">http://allenyoung.javaeye.com/blog/104662</a>&nbsp;
          发表时间: 2007年07月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在view里面可以用h来escape html内容。那在controller里面呢？我的需求是把一些数据用json格式发送到前台，这些数据是用户之前输入的。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/104662#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 24 Jul 2007 10:24:54 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/104662</link>
        <guid>http://allenyoung.javaeye.com/blog/104662</guid>
      </item>
      <item>
        <title>ActiveRecord中表关联的一个问题，belongs_to和has_many不是一一对应的情况。</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/102903" style="color:red;">http://allenyoung.javaeye.com/blog/102903</a>&nbsp;
          发表时间: 2007年07月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一个挺有意思的问题，想了半天没有解决办法。<br /><br />情景是这样的：系统中有两种category，system_category和user_category，所有属性都一样，只是一个是系统分类，一个是用户自己的分类。比如javaeye就是有这样的机制。用户发文时可以同时选择system_category和user_category。假如数据库的设计是system_category和user_category都在一张表categories中。那么Category和Article类的代码大致如下：<br /><pre name="code" class="ruby">
# Category.rb
class Category &lt; ActiveRecord::Base
  has_many :articles
end
</pre><br /><pre name="code" class="ruby">
# Article.rb
class Article &lt; ActiveRecord::Base
  belongs_to  :system_category, :class_name   => "Category", :foreign_key => "system_category_id"
  belongs_to  :user_category,   :class_name   => "Category", :foreign_key => "user_category_id"
end
</pre><br />各位肯定已经注意到了，两边的has_many和belongs_to不是一一对应的。这个时候执行一些语句，结果如下（假设id为1的user cateogry有两个article，id分别为1，2）：<br /><pre name="code" class="ruby">
Article.find_by_id(1).user_category.id  # => 1
Article.find_by_id(2).user_category.id  # => 1
Category.find_by_id(1).articles            # 出错，说articles没有category_id。
</pre><br />出现以上错误是正常的，但是有什么方法可以解决这个问题吗？当然，我可以在category中声明两个has_many，但是这样显然不符合应用逻辑。我也尝试过使用:finder_sql，但是不知道怎么得到当前category的id，也就没办法手工做查询了。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/102903#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 19 Jul 2007 18:15:50 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/102903</link>
        <guid>http://allenyoung.javaeye.com/blog/102903</guid>
      </item>
      <item>
        <title>Rails routes mapping的一个奇怪的问题。顺便讨论一下如何做RESTful的paginate。</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/102354" style="color:red;">http://allenyoung.javaeye.com/blog/102354</a>&nbsp;
          发表时间: 2007年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          大家可以试验一下，在我的开发环境中会出现这个问题，不知道是不是只有我有问题。做法如下：<br /><ul><li>随便建立一个Rails工程；</li><li>随便生成一个scaffold_resource，比如map.resources :articles；</li><li>在routes.rb中加入如下代码，添加自己的routes mapping：</li><pre name="code" class="ruby">
map.articles_paginate "articles;paginate", :controller => 'articles', :action => 'paginate', :conditions => { :method => :get }
</pre><li>在ArticlesController中声明方法paginate，然后随便以任何方式从view中调用这个url。</li></ul><br />我这里产生的结果是unknow action。这说明routes mapping已经起作用了，但是找不到paginate方法。<br /><br />我知道我想要的mapping可以通过rails自带的方式实现，不需要自己写mapping。但是由于某些原因，我无法使用自带的实现方式。而且按道理我自己mapping也不应该有问题。请各位看看是怎么回事儿。<br /><br />另外，顺便讨论一下RESTful的paginate应该如何实现。OK，我知道有人会说不要为了REST而REST，要用在合适的地方。这我同意，就是想讨论一下。如果结论就是REST不适合用在paginate上，那就不用呗。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/102354#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 18 Jul 2007 09:33:25 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/102354</link>
        <guid>http://allenyoung.javaeye.com/blog/102354</guid>
      </item>
      <item>
        <title>［讨论］部署Rails的最佳方案是什么？</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/98435" style="color:red;">http://allenyoung.javaeye.com/blog/98435</a>&nbsp;
          发表时间: 2007年07月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          从来没真正部署过一个production级别的rails应用，但是9月份很可能要部署一个，所以最近也开始关注Rails的部署问题。这里算是抛砖引玉吧，还请各位有经验的同志热烈讨论，我想很多人也都对这方面很感兴趣。<br /><br />Robbin之前的帖子里面讨论过如何选择Rails的部署方案，也挺详细的，我估计硬件和操作系统方面大家分歧应该不大，总归是linux，服务器越强劲，内存越大越好。所以问题就到了软件方面。数据库大概也不用怎么讨论，mysql之类的东西大家心里都有数。关键还是server的问题。<br /><br />JavaEye现在用的server应该是lighttpd和fastcgi吧，从大家浏览网站的体验上看，性能还是不错的。Robbin有写文章讲过如何安装这些server，但是很想知道选择这些server的原因。apache应该是最传统的选择，为什么Robbin没有选它呢？<br /><br />ThoughtWorks的RubyWorks选择的是HAProxy和Mongel，这里没有静态web server，文档里说可以用apache和一个叫nginx的东东。我想大公司选择这些东东作为RubyWorks的默认安装，肯定是有原因的吧。那它们的lighttpd+fastcgi比较起来如何呢？gigix也许可以解释一下。<br /><br />如果有哪位大哥可以总结一下目前比较流行的server组合，说说各自的优缺点，那小弟真是感激不尽啊。<br /><br />另外，我个人觉得选择server的时候，不单单要看功能和性能方面，还要看安装配置是不是比较简单，不知道各位是否同意这一观点呢？
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/98435#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 06 Jul 2007 13:46:00 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/98435</link>
        <guid>http://allenyoung.javaeye.com/blog/98435</guid>
      </item>
      <item>
        <title>Rails中使用REST，登录相关的问题，如何获得当前正在处理的url？</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/97358" style="color:red;">http://allenyoung.javaeye.com/blog/97358</a>&nbsp;
          发表时间: 2007年07月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          如果整个routes是使用传统的mvc方式实现的话，我们可以简单地记录一下当前的controller和action的名字，等到登录成功之后就可以redirect过去。<br /><br />但是如果使用REST，则就不能简单地记录controller和action，例如/articles/1;edit这样的url就比较特别。另外一个问题是，除了要记录url外，还要记录使用什么HTTP Method，是GET, Post, PUT还是DELETE。<br /><br />如果涉及到的action就是标准的index, create, new, show, update, edit, destory，那么可以使用一个case判断，然后调用相应的url helper，比如articles_url，然后把HTTP Method以硬编码的方式写入。但是如果在routes.rb里面添加了自己的routine，比如<br /><pre name="code" class="ruby">
map.resource :articles, :collection => { :recent => :get }
</pre><br />那么又要怎么办呢？自己加入的routine有三种类型:collection, :member和:new，HTTP Method也可以随意指定，那么要怎么生成url呢？
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/97358#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 03 Jul 2007 16:39:07 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/97358</link>
        <guid>http://allenyoung.javaeye.com/blog/97358</guid>
      </item>
      <item>
        <title>Eclipse 3.3携Europa正式发布了</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/96000" style="color:red;">http://allenyoung.javaeye.com/blog/96000</a>&nbsp;
          发表时间: 2007年07月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          刚刚逛了一圈论坛，竟然没人提到这么个消息，难道Eclipse真的没落啦？<br /><br />Europa的事儿咱就不说了，之前有一位仁兄已经讲得很清楚了。今天上午到Eclipse主页上溜达了一下，发现3.3在昨天发布了，应该算是一个不小的新闻哦。记得前一阵子总有人说Eclipse发布的速度变慢了，跟不上NetBeans，看来这次发布算是小小地安抚了一下Eclipse的粉丝们啊。<br /><br />主页上明显的一个变动是提供了针对不同类型开发者的不同版本的下载，而不再只是一味地SDK=Platform+JDT+PDE了，算是不错的改进。另外一个值得注意的地方是3.3版本默认加入了Mylyn这个东东。Mylyn就是以前的Mylar（我总觉得新名字没有老名字好），是做Task Focused Development的一个东东。具体来说就是可以把很多东西标记为task，然后从task的角度看整个project，这样整体感觉会清爽很多。Mylyn还支持与BugZilla，Trac还有JIRA的整合，你可以在Mylyn里面创建这些Issue Tracking System中的task，然后做做同步之类的，应该是很方便的。另外Subclipse也有一个支持Mylyn的版本。<br /><br />由于最近本人关注Ruby比较多，因此特意看了一下DLTK。目前还是0.9版本，试用起来对Ruby的支持很不错，比当前的NetBeans要好。一个例子是：DLTK可以根据变量的类型做代码提示，而NetBeans目前是把所有的东西都提示出来（比如一个对Array变量也会提示出ActiveRecord的方法）。但可惜的是DLTK没有对Ruby on Rails的支持，所以目前还是NetBeans更全面一些。CodeGear在今年第3季度会推出基于DLTK的Ruby IDE，支持Ruby on Rails，而且号称会是best in the world，多少有些让人期待。但是很有可能这个东东是要钱的，哎～<br /><br />有一个比较讽刺的地方，我想使用Eclipse作为Ruby on Rails的IDE，完全是为了Skept这个东东。如果可行，就可以在一个IDE里面得到对Ruby on Rails和ExtJS相当不错的支持了。但是问题在于，当前的Skept不能运行在Eclipse 3.3下，而DLTK非要使用Eclipse 3.3不可。Eclipse的兼容问题我老早就诟病过了，看来在今后的很长时间里还是不得不忍受下去啊。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/96000#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 01 Jul 2007 12:57:18 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/96000</link>
        <guid>http://allenyoung.javaeye.com/blog/96000</guid>
      </item>
      <item>
        <title>在apple上使用ruby的郁闷事儿</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/93514" style="color:red;">http://allenyoung.javaeye.com/blog/93514</a>&nbsp;
          发表时间: 2007年06月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          安装了那个Locomotive，还有iTerm，还有Textmate，以为就万事大吉了。然后运行gem安装ferret，没想到竟然报错说无法make。到命令行下试了一下，果然不能使用gcc啊，make啊这样的东东。Mac不是Unix-based灭？<br /><br />于是去google了一下，发现要装个xcode才能搞定这些东东，敢情apple把这些东西都给踢掉了啊。在去看看xcode，倒还是免费的，不过安装程序就有900M多，好不容易下载下来了，安装竟然要将近3GB!!可怜我一共只有40GB硬盘的小白啊...<br /><br />你说我一不会去写cocoa之类的东东，而不会在xcode里面写java。我就是想要个gcc和make，怎么就这么难呢～对apple的这个行为还真是不解。不知道哪位有经验能告诉我怎么能绕过xcode，实在太展地方了！
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/93514#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 23 Jun 2007 19:49:17 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/93514</link>
        <guid>http://allenyoung.javaeye.com/blog/93514</guid>
      </item>
      <item>
        <title>在ubuntu下安装ruby需要注意的事情</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/93512" style="color:red;">http://allenyoung.javaeye.com/blog/93512</a>&nbsp;
          发表时间: 2007年06月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这里说的是通过apt-get安装ruby，自己编译的情况就免了。<br /><br />首先，在安装ruby本身时一定要把ruby和ruby-dev全安装了。现在的版本是1.8，因此应该执行如下命令<br /><pre name="code" class="java">
sudo apt-get install ruby1.8 ruby1.8-dev rubygems
</pre><br />这是因为许多plugin或者gems都要依赖dev下面的东东，比如ferret就要用到一个叫mkmf的东西，后者就是包含在dev中的。<br /><br />然后可以gem或者apt-get来安装rails，不过推荐前者，因为版本肯定是最新的。比如我用的源里面的rails还不是1.2的呢，用apt-get就不好了。<br /><br />最后就是找找这些东东都安装在哪儿了，可以在根目录下运行find命令<br /><pre name="code" class="java">
sudo find -iname *ruby* >> result.txt
</pre><br />下面是我电脑上的运行结果<br /><pre name="code" class="java">
./usr/share/doc/ruby
./usr/share/doc/ruby/ruby-policy.sgml.gz
./usr/share/doc/ruby/ruby-policy.txt.gz
./usr/share/doc/ruby/ruby-policy.html
./usr/share/doc/ruby/ruby-policy.html/ch-ruby.html
./usr/share/doc/ruby/ruby-policy.html/ap-ruby1.8_bundled_modules.html
./usr/share/doc/rubygems
./usr/share/doc/libreadline-ruby1.8
./usr/share/doc/ruby1.8-dev
./usr/share/doc/libruby1.8
./usr/share/doc/ruby1.8
./usr/share/doc/libopenssl-ruby1.8
./usr/share/doc/libgems-ruby1.8
./usr/share/doc/libgems-ruby1.8/test/data/legacy/keyedlist-0.4.0.ruby
./usr/share/gedit-2/plugins/snippets/ruby.xml
./usr/share/gtksourceview-1.0/language-specs/ruby.lang
./usr/share/man/man1/ruby1.8.1.gz
./usr/share/man/man1/ruby.1.gz
./usr/share/mime/application/x-ruby.xml
./usr/share/nano/ruby.nanorc
./usr/bin/update_rubygems
./usr/bin/ruby
./usr/bin/ruby1.8
./usr/lib/libruby1.8-static.a
./usr/lib/ruby
./usr/lib/ruby/gems/1.8/doc/rubygems-0.9.4
./usr/lib/ruby/gems/1.8/doc/rubygems-0.9.4/ri/Gem/Specification/to_ruby-i.yaml
./usr/lib/ruby/gems/1.8/doc/rubygems-0.9.4/ri/Gem/Commands/UpdateCommand/do_rubygems_update-i.yaml
./usr/lib/ruby/gems/1.8/doc/rubygems-0.9.4/ri/Gem/ruby-c.yaml
./usr/lib/ruby/gems/1.8/doc/rubygems-0.9.4/rdoc/files/lib/rubygems_rb.html
./usr/lib/ruby/gems/1.8/doc/rubygems-0.9.4/rdoc/files/lib/rubygems
./usr/lib/ruby/gems/1.8/doc/rubygems-0.9.4/rdoc/files/lib/rubygems/rubygems_version_rb.html
./usr/lib/ruby/gems/1.8/doc/actionwebservice-1.2.3/ri/ActionWebService/Protocol/Soap/SoapMarshaler/ruby_to_soap-i.yaml
./usr/lib/ruby/gems/1.8/doc/actionwebservice-1.2.3/ri/ActionWebService/Protocol/Soap/SoapMarshaler/soap_to_ruby-i.yaml
./usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake/ruby182_test_unit_fix.rb
./usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake/contrib/rubyforgepublisher.rb
./usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/ruby_version_check.rb
./usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/rubyprof_ext.rb
./usr/lib/ruby/1.8/rubygems
./usr/lib/ruby/1.8/rubygems/rubygems_version.rb
./usr/lib/ruby/1.8/rubygems.rb
./usr/lib/ruby/1.8/yaml/rubytypes.rb
./usr/lib/ruby/1.8/soap/mapping/rubytypeFactory.rb
./usr/lib/ruby/1.8/wsdl/xmlSchema/xsd2ruby.rb
./usr/lib/ruby/1.8/wsdl/soap/wsdl2ruby.rb
./usr/lib/ruby/1.8/irb/ruby-token.rb
./usr/lib/ruby/1.8/irb/ruby-lex.rb
./usr/lib/ruby/1.8/i486-linux/rubyio.h
./usr/lib/ruby/1.8/i486-linux/rubysig.h
./usr/lib/ruby/1.8/i486-linux/ruby.h
./usr/lib/ruby/1.8/rubyunit.rb
./usr/lib/libruby1.8.so.1.8.5
./usr/lib/libruby1.8.so
./usr/lib/libruby1.8.so.1.8
./usr/local/lib/site_ruby
./usr/local/lib/site_ruby/1.8/rubygems
./usr/local/lib/site_ruby/1.8/rubygems/rubygems_version.rb
./usr/local/lib/site_ruby/1.8/rubygems.rb
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/93512#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 23 Jun 2007 19:41:19 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/93512</link>
        <guid>http://allenyoung.javaeye.com/blog/93512</guid>
      </item>
      <item>
        <title>基于model动态地ComboBox为生成options</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/91290" style="color:red;">http://allenyoung.javaeye.com/blog/91290</a>&nbsp;
          发表时间: 2007年06月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在使用RoR创建form时，很多时候需要基于model之间的关系创建ComboBox。RoR提供了很多方便的helper方法帮助我们完成一个 form的创建。例如，如果想要为article创建一个form，并且要为article选择category时，可以使用如下方法：<br /><pre name="code" class="ruby">
&lt;% form_for(:material, :url => url, :html => { :method => method }) do |f| %>
  &lt;p>&lt;label>Name&lt;/label>&lt;br/>
  &lt;%= f.text_field :name %>&lt;/p>
  &lt;p>&lt;label>Category&lt;/label>&lt;br/>
  &lt;%= f.select :category_id, get_category_select_options %>&lt;/p>
  &lt;p>&lt;label>Content&lt;/label>&lt;br/>
  &lt;%= f.text_area :content %>&lt;/p>
  &lt;p>&lt;%= submit_tag 'Create' %>&lt;/p>
&lt;% end %>
</pre><br />而其中的get_category_select_options可以采用如下实现方式（定义在articles_helper中）：<br /><pre name="code" class="ruby">
def get_category_select_options  
  Category.find(:all, :order => 'name').collect { |item| [item.name, item.id] }.insert(0, ['Please select...', nil])  
end
</pre><br />以上代码通过Category类找到所有的category，然后使用其中的name和id属性（注意顺序）作为options的label和data，最后在加入一个默认的选项“Please select...”。一切都很简单，不是吗？<br /><br />然而，如果model之间的关联稍微复杂一点儿，就可能会在很多地方使用类似的方法获得ComboBox的选项，那么为每个可能成为ComboBox选项的model都写这么一个方法实在是太麻烦了。如果是在Java世界中，我们可以很快想到使用反射来解决这个问题。也就是说在知道类名的情况下，用 Class.forName得到Class对象，然后在调用其上的find方法之类的。但是我们使用的是Ruby这个号称动态能力超强的语言，有什么更容易的做法吗？当然，代码如下：<br /><pre name="code" class="ruby">
def get_select_options_for(symbol)  
  Object.const_get(symbol.to_s.capitalize).find(:all, :order => 'name').collect { |item| [item.name, item.id] }.insert(0, ['Please select...', nil])  
end
</pre><br />关键就在这个const_get方法上，它是Module的一个静态方法，所以我们可以通过Object来调用它。我们把类名传递进去，它就可以返回这个类。但是注意这里的写法，我们可以在返回类上直接调用find，而不是像Java那样clazz.getMethod(...).invoke (...)，是不是非常的方便呢？我们可以把这个方法定义在application_helper中，这样在所有的view中就都可以使用了，那么上面的 form代码就变成了如下这样：<br /><pre name="code" class="ruby">
&lt;% form_for(:material, :url => url, :html => { :method => method }) do |f| %>
  &lt;p>&lt;label>Name&lt;/label>&lt;br/>
  &lt;%= f.text_field :name %>&lt;/p>
  &lt;p>&lt;label>Category&lt;/label>&lt;br/>
  &lt;%= f.select :category_id, get_select_options_for(:category) %>&lt;/p>
  &lt;p>&lt;label>Content&lt;/label>&lt;br/>
  &lt;%= f.text_area :content %>&lt;/p>
  &lt;p>&lt;%= submit_tag 'Create' %>&lt;/p>
&lt;% end %>
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/91290#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 17 Jun 2007 16:17:59 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/91290</link>
        <guid>http://allenyoung.javaeye.com/blog/91290</guid>
      </item>
      <item>
        <title>Linux下面的ftp客户端还是lftp好啊～</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/90743" style="color:red;">http://allenyoung.javaeye.com/blog/90743</a>&nbsp;
          发表时间: 2007年06月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本来一直都是用Windows的，虽然早就想全面转移到Linux上面来，但是一直比较懒，而且对Linux也不熟，所以一直都没有真正实现。昨天中了一个比较恶心的病毒，忙于杀毒之余，一气之下就决定全面转到Linux上来了。再加上另外一台是apple的本本，看来真是快要告别Windows了，哈哈。<br />
<br />
花了好长时间才把文件都备份到了ftp服务器上（服务器是Windows的desktop），然后安装Ubuntu，这些都是轻车熟路了，然后更新系统，同时开始把文件都下载回来。然后，著名的乱码问题就出现了。<br />
<br />
先是用FileZilla试验了一下，不行；然后gFTP也不行，虽说有补丁，但是貌似和最新版本不兼容，我也懒得换到旧版本了。干脆就用console好了。玩了一下自带的lftp，真是不错，功能很强大，编码也可以灵活设置和转换，还可以加bookmark。<br />
<br />
后来去搜了一下，原来lftp已经是非常老牌的东东了，看来自己还是对Linux不够熟悉啊，要快快融入进来才好。
          <br/>
          <span style="color:red;">
            <a href="http://allenyoung.javaeye.com/blog/90743#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Jun 2007 12:55:12 +0800</pubDate>
        <link>http://allenyoung.javaeye.com/blog/90743</link>
        <guid>http://allenyoung.javaeye.com/blog/90743</guid>
      </item>
      <item>
        <title>关于REST的一点想法，欢迎大家讨论。</title>
        <author>AllenYoung</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://allenyoung.javaeye.com">AllenYoung</a>&nbsp;
          链接：<a href="http://allenyoung.javaeye.com/blog/70113" style="color:red;">http://allenyoung.javaeye.com/blog/70113</a>&nbsp;
          发表时间: 2007年04月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这阵子正打算用Rails做个东东，所以开始系统地学习起了Rails。巧合的是，大概两周前，dlee邀请我加入Fielding博士关于REST的那篇论文的翻译团队。可以说Rails和REST这两个最热门的词汇几乎同时挤入了我的生活。随着我对Rails的学习和对[Fielding]的翻译，我也开始对REST产生了一些不太成熟的想法，写在这里与大家分享，同时也起到抛砖引玉的作用，欢迎大家讨论。<br />
<br />
先复习一下REST的基本思想。[Fielding]把REST形式化地定义为一种架构风格（architecture style），它有架构元素（element）和架构约束（constraint）组成。这些概念比较晦涩难懂，而且我们做工程的往往并不需要形而上的理解。我们只知道，REST是一种针对网络应用的设计和开发方式，可以降低开发的复杂性，提高系统的可伸缩性。REST提出了一些设计概念和准则：<br />
<ol>
    <li>网络上的所有事物都被抽象为资源（resource）；</li>
    <li>每个资源对应一个唯一的资源标识（resource identifier）；</li>
    <li>通过通用的连接器接口（generic connector interface）对资源进行操作；</li>
    <li>对资源的各种操作不会改变资源标识；</li>
    <li>所有的操作都是无状态的（stateless）。</li>
</ol>
对于当今最常见的网络应用来说，resource identifier是url，generic connector interface是HTTP，第4条准则就是我们常说的url不变性。这些概念中的resouce最容易使人产生误解。resouce所指的并不是数据，而是数据+特定的表现形式（representation），这也是为什么REST的全名是Representational State Transfer的原因。举个例子来说，&ldquo;本月卖得最好的10本书&rdquo;和&ldquo;你最喜欢的10本书&rdquo;在数据上可能有重叠（有一本书即卖得好，你又喜欢），甚至完全相同。但是它们的representation不同，因此是不同的resource。<br />
<br />
REST之所以能够简化开发，是因为其引入的架构约束，比如Rails 1.2中对REST的实现默认把controller中的方法限制在7个：index、show、new、edit、create、update和destory，这实际上就是对CURD的实现。更进一步讲，Rails（也是当今大部分网络应用）使用HTTP作为generic connector interface，HTTP则把对一个url的操作限制在了4个之内：GET、POST、PUT和DELETE。<br />
<br />
REST之所以能够提高系统的可伸缩性，是因为它强制所有操作都是stateless的，这样就没有context的约束，如果要做分布式、做集群，就不需要考虑context的问题了。同时，它令系统可以有效地使用pool。REST对性能的另一个提升来自其对client和server任务的分配：server只负责提供resource以及操作resource的服务，而client要根据resource中的data和representation自己做render。这就减少了服务器的开销。<br />
<br />
既然REST有这样的好处，那我们应该义无反顾地拥抱它啊！目前一些大牛（像DHH）都已经开始投入到了REST的世界，那我们这些人应该做什么或者说思考写什么你呢？我觉得我们应该思考两个问题：<br />
<ol>
    <li>如何使用REST；</li>
    <li>REST和MVC的关系。</li>
</ol>
第一个问题假设REST是我们应该采用的架构，然后讨论如何使用；第二个问题则要说明REST和当前最普遍应用的MVC是什么关系，互补还是取代？<br />
<br />
我们先来谈谈第一个问题，如何使用REST。我感觉，REST除了给我们带来了一个崭新的架构以外，还有一个重要的贡献是在开发系统过程中的一种新的思维方式：通过url来设计系统的结构。根据REST，每个url都代表一个resource，而整个系统就是由这些resource组成的。因此，如果url是设计良好的，那么系统的结构就也应该是设计良好的。对于非高手级的开发人员来说，考虑一个系统如何架构总是一个很抽象的问题。敏捷开发所提倡的Test Driven Development，其好处之一（我觉得是最大的好处）就是可以通过testcase直观地设计系统的接口。比如在还没有创建一个class的时候就编写一个testcase，虽然设置不能通过编译，但是testcase中的方法调用可以很好地从class使用者的角度反映出需要的接口，从而为class的设计提供了直观的表现。这与在REST架构中通过url设计系统结构非常类似。虽然我们连一个功能都没有实现，但是我们可以先设计出我们认为合理的url，这些url甚至不能连接到任何page或action，但是它们直观地告诉我们：系统对用户的访问接口就应该是这样。根据这些url，我们可以很方便地设计系统的结构。<br />
<br />
让我在这里重申一遍：<strong>REST允许我们通过url设计系统，就像Test Driven Development允许我们使用testcase设计class接口一样。<br />
<br />
</strong>OK，既然url有这样的好处，那我们就着重讨论一下如何设计url。网络应用通常都是有hierarchy的，像棵大树。我们通常希望url也能反映出资源的层次性。比如对于一个blog应用：/articles表示所有的文章，/articles/1表示id为1的文章，这都比较直观。遗憾的是，网络应用的资源结构永远不会如此简单。因此人们常常会问这样一个问题：RESTful的url能覆盖所有的用户请求吗？比如，login如何RESTful？search如何RESTful？<br />
<br />
从REST的概念上来看，所有可以被抽象为资源的东东都可以使用RESTful的url。因此对于上面的两个问题，如果login和search可以被抽象为资源，那么就可以使用RESTful的url。search比较简单，因为它会返回搜索结果，因此可以被抽象为资源，并且只实现index方法就可以了（只需要显示搜索结果，没有create、destory之类的东西）。然而这里面也有一个问题：search的关键字如何传给server？index方法显然应该使用HTTP GET，这会把关键字加到url后面，当然不符合REST的风格。要解决这个问题，可以把每次search看作一个资源，因此要创建create和index方法，create用来在用户点击&ldquo;搜索&rdquo;按钮是通过HTTP POST把关键字传给server，然后index则用来显示搜索结果。这样一来，我们还可以记录用户的搜索历史。使用同样的方法，我们也可以对login应用REST，即每次login动作是一个资源。<br />
<br />
现在，我们来复杂一些的东东。如何用url表达&ldquo;category为ruby的article&rdquo;？一开始可能想到的是/category/ruby/articles，这种想法很直观。但是我觉得里面的category是不需要的，我们可以直接把&ldquo;/ruby&rdquo;理解为&ldquo;category是ruby&rdquo;，也就是说&ldquo;ruby&rdquo;出现的位置说明了它指的就是category。OK，/ruby/articl