<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-15313887</id><updated>2011-04-21T14:01:43.983-07:00</updated><category term='ruby'/><category term='ruby bug'/><category term='emacs ruby rspec'/><title type='text'>Free Mind</title><subtitle type='html'>the Free Mind of pluskid</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pluskid.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://pluskid.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>pluskid</name><uri>http://www.blogger.com/profile/17997317415745134928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15313887.post-1177366969421112793</id><published>2009-02-10T04:44:00.000-08:00</published><updated>2009-02-10T04:46:06.364-08:00</updated><title type='text'>New Blog</title><content type='html'>It is here: &lt;a href="http://blog.pluskid.org"&gt;http://blog.pluskid.org&lt;/a&gt; , and the posts in the original blog has been archived here: &lt;a href="http://lifegoo.pluskid.org"&gt;http://lifegoo.pluskid.org&lt;/a&gt; .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15313887-1177366969421112793?l=pluskid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pluskid.blogspot.com/feeds/1177366969421112793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15313887&amp;postID=1177366969421112793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/1177366969421112793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/1177366969421112793'/><link rel='alternate' type='text/html' href='http://pluskid.blogspot.com/2009/02/new-blog.html' title='New Blog'/><author><name>pluskid</name><uri>http://www.blogger.com/profile/17997317415745134928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15313887.post-7918745050998856043</id><published>2008-10-28T20:20:00.000-07:00</published><updated>2008-10-28T20:21:05.421-07:00</updated><title type='text'>pluskid.lifegoo.com 大迁移</title><content type='html'>&lt;p&gt;事情确实发生得有点突然，昨天晚上登上 Google Talk ，&lt;a href="http://jack.lifegoo.com/"&gt;Jack&lt;/a&gt; 突然告诉我托管的服务器在 11 月份就要拿回来了。那代表所有 lifegoo.com 上的应用都会下线吧。这个 blog 是去年五月份的时候我请求帮忙开通的，非常好用，真的要感谢 Jack 和 &lt;a href="http://sishen.lifegoo.com/"&gt;sishen&lt;/a&gt; 了！&lt;/p&gt; &lt;p&gt;不过，现在得到这个消息还真有些伤心，毕竟是用了这么长时间的 blog ，incoming link 也是有不少的。但是总之还是先把数据备份下来吧。我想先用 wordpress 的方式备份一份数据库，再用普通网页抓取的方式把网站爬下来，不过好像 quark 昨天晚上已经帮我爬过了，还做成了一个 chm ，待会找他要去。&lt;/p&gt; &lt;p&gt;备份下来之后还要考虑今后的去处呢。一时之间都没有想到哪个地方比较好用又稳定的。也许是该去注册一个域名了，不知道现在注册域名费用如何。可是如 果单单是为了放一个 blog 去租一个虚拟空间的话，似乎太浪费了，而且这些价格啊、在哪里租比较好啊之类的也都还很不了解。时间比较仓促，似乎现在 blogger 还没有被封掉，于是暂时用 blogger 上的那个吧： &lt;a href="http://pluskid.blogspot.com/"&gt;http://pluskid.blogspot.com&lt;/a&gt; ，如果我找到了新的地方，会在那里贴出来。lifegoo 这里也不清楚具体哪天会下线，所以我待会把这篇文章也贴过去。&lt;/p&gt; &lt;p&gt;我想 blog 我还是希望继续写的，虽然现在频率比以前已经低了很多了吧。moonykily 曾经跟我说他觉得写技术 blog 的人都是脑子进水了，blog 本来就是用来抒发自己心情的。当然我是不会同意他的这个观点的，且不说写技术 blog 能够让知识得到分享这样的话吧，更自私的观点就是：如果你能把自己知道的东西给别人描述清楚的话，你会掌握得更加牢靠。而有些东西当你准备要写下来的时 候，你才会发现原来自己根本没有弄清楚。我写 blog 一般会花掉半天到两天不等的时间，但是大部分时候我还是觉得是有收获的。&lt;/p&gt; &lt;p&gt;所以，我还是先去备份数据了，之后怎么迁移还真是个麻烦事，一时也想不清楚，不知道大家有什么好的主意没有？&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15313887-7918745050998856043?l=pluskid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pluskid.blogspot.com/feeds/7918745050998856043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15313887&amp;postID=7918745050998856043' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/7918745050998856043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/7918745050998856043'/><link rel='alternate' type='text/html' href='http://pluskid.blogspot.com/2008/10/pluskidlifegoocom.html' title='pluskid.lifegoo.com 大迁移'/><author><name>pluskid</name><uri>http://www.blogger.com/profile/17997317415745134928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15313887.post-4466983702129483049</id><published>2008-03-01T18:17:00.000-08:00</published><updated>2008-03-01T18:19:34.320-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby bug'/><title type='text'>Fixnum Overflow in Ruby’s Hash Implementation</title><content type='html'>The &lt;a href="http://pluskid.lifegoo.com/?p=286"&gt;original post&lt;/a&gt; is on my &lt;a href="http://pluskid.lifegoo.com/"&gt;main blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ruby’s build-in &lt;code&gt;Hash&lt;/code&gt; is the first-choice if you want to do searching. Using your own customized object as hash key is simple: define the following two method for your object: &lt;ul&gt;&lt;li&gt;&lt;code&gt;hash&lt;/code&gt;: to get the hash code of the object.&lt;/li&gt;&lt;li&gt;&lt;code&gt;eql?&lt;/code&gt;: to compare whether two object are equal.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;When working to improve the performance of &lt;a href="http://rmmseg.rubyforge.org/"&gt;RMMSeg&lt;/a&gt;, I tried to implement a &lt;code&gt;Substring&lt;/code&gt; class which can hold a reference to a big chunk of text instead of doing an expensive copy. Then I implemented the &lt;code&gt;hash&lt;/code&gt; and &lt;code&gt;eql?&lt;/code&gt; method. The hash value calculated is identical to the related &lt;code&gt;String&lt;/code&gt;, and &lt;code&gt;eql?&lt;/code&gt; is properly implemented. But the whole thing seemed not working quite well.&lt;/p&gt; &lt;p&gt;&lt;span id="more-286"&gt;&lt;/span&gt;I though it’s my code’s fault because it’s the first time for me to write a C extension of Ruby. I use gdb to trace the program — it’s very hard to do, because &lt;code&gt;Hash&lt;/code&gt; is a very commonly used data structure in Ruby. Many core libraries use it. &lt;img src="http://pluskid.lifegoo.com/wp-content/plugins/smilies-themer/adiumicons/sad.png" alt=":(" class="wp-smiley" /&gt; &lt;/p&gt; &lt;p&gt;However, finally I figured it out (after a sleep) and created a small piece of code to reproduce it:&lt;/p&gt;  &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="ruby"&gt;&lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;class&lt;/span&gt; MyStr&lt;br /&gt; &lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;def&lt;/span&gt; initialize&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;(&lt;/span&gt;str&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 255); font-weight: bold;"&gt;@str&lt;/span&gt; = str&lt;br /&gt; &lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;def&lt;/span&gt; hash&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 255); font-weight: bold;"&gt;@str&lt;/span&gt;.&lt;span style="color: rgb(153, 0, 204);"&gt;hash&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;def&lt;/span&gt; eql?&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;(&lt;/span&gt;o&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 255); font-weight: bold;"&gt;@str&lt;/span&gt;.&lt;span style="color: rgb(153, 0, 204);"&gt;eql&lt;/span&gt;?&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;(&lt;/span&gt;o&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 102, 204); font-weight: bold;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;s1 = &lt;span style="color: rgb(153, 102, 0);"&gt;"foo"&lt;/span&gt;&lt;br /&gt;s2 = &lt;span style="color: rgb(153, 102, 0);"&gt;"This"&lt;/span&gt;&lt;br /&gt;my_s1 = MyStr.&lt;span style="color: rgb(153, 0, 204);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;(&lt;/span&gt;s1&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;)&lt;/span&gt;&lt;br /&gt;my_s2 = MyStr.&lt;span style="color: rgb(153, 0, 204);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;(&lt;/span&gt;s2&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;)&lt;/span&gt;&lt;br /&gt;h = &lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;{&lt;/span&gt; s1 =&gt; &lt;span style="color: rgb(153, 102, 0);"&gt;"value of foo"&lt;/span&gt;, s2 =&gt; &lt;span style="color: rgb(153, 102, 0);"&gt;"value of This"&lt;/span&gt; &lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 102); font-weight: bold;"&gt;puts&lt;/span&gt; &lt;span style="color: rgb(153, 102, 0);"&gt;"h[my_s1] = #{h[my_s1].inspect}"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 102); font-weight: bold;"&gt;puts&lt;/span&gt; &lt;span style="color: rgb(153, 102, 0);"&gt;"h[my_s2] = #{h[my_s2].inspect}"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;The expected output should be&lt;/p&gt;  &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="text"&gt;h[my_s1] = "value of foo"&lt;br /&gt;h[my_s2] = "value of This"&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;but the actual output is&lt;/p&gt;  &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="text"&gt;h[my_s1] = "value of foo"&lt;br /&gt;h[my_s2] = nil&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;So what’s wrong with is? Why “foo” is right but “This” is wrong? Looking at the code of &lt;code&gt;Hash&lt;/code&gt; in Ruby answers the question. Ruby’s treating &lt;code&gt;String&lt;/code&gt; specially. When the key is a &lt;code&gt;String&lt;/code&gt;, it use &lt;code&gt;rb_str_hash&lt;/code&gt; directly to calculate the hash value.&lt;/p&gt; &lt;p&gt;&lt;code&gt;rb_str_hash&lt;/code&gt; returns an &lt;code&gt;int&lt;/code&gt;. But user customized objects don’t have this special treatment. The &lt;code&gt;hash&lt;/code&gt; method is called in the Ruby environment returning a &lt;code&gt;Fixnum&lt;/code&gt; which finally converted to an &lt;code&gt;int&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;The problem is that the value range of a &lt;code&gt;Fixnum&lt;/code&gt; is small than &lt;code&gt;int&lt;/code&gt;. The calculated hash value of “This”, 2073740424, when converted to &lt;code&gt;Fixnum&lt;/code&gt; and then converting back, finally becomes -73743224.&lt;/p&gt; &lt;p&gt;That’s the problem. When key is a &lt;code&gt;String&lt;/code&gt;, its hash is the original 2073740424. But when not, its hash becomes the weird -73743224. It’s a bug, not only with &lt;code&gt;String&lt;/code&gt;, but also &lt;code&gt;Symbol&lt;/code&gt; and &lt;code&gt;Fixnum&lt;/code&gt;. I’ve post the bug report and a suggested patch to ruby-core ML. Hope it get fixed soon. &lt;img src="http://pluskid.lifegoo.com/wp-content/plugins/smilies-themer/adiumicons/happy.png" alt=":)" class="wp-smiley" /&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15313887-4466983702129483049?l=pluskid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pluskid.blogspot.com/feeds/4466983702129483049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15313887&amp;postID=4466983702129483049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/4466983702129483049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/4466983702129483049'/><link rel='alternate' type='text/html' href='http://pluskid.blogspot.com/2008/03/fixnum-overflow-in-rubys-hash.html' title='Fixnum Overflow in Ruby’s Hash Implementation'/><author><name>pluskid</name><uri>http://www.blogger.com/profile/17997317415745134928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15313887.post-2989794361438400657</id><published>2008-02-26T02:39:00.000-08:00</published><updated>2008-02-26T02:41:27.384-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>[ANN] RMMSeg 0.1.2 Released</title><content type='html'>Mainly performance improvement.&lt;br /&gt;&lt;br /&gt;rmmseg version 0.1.2&lt;br /&gt;by pluskid&lt;br /&gt;&lt;a href="http://rmmseg.rubyforge.org"&gt;http://rmmseg.rubyforge.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;== DESCRIPTION&lt;br /&gt;&lt;br /&gt;RMMSeg is an implementation of MMSEG Chinese word segmentation&lt;br /&gt;algorithm. It is based on two variants of maximum matching&lt;br /&gt;algorithms. Two algorithms are available for using:&lt;br /&gt;&lt;br /&gt;* simple algorithm that uses only forward maximum matching.&lt;br /&gt;* complex algorithm that uses three-word chunk maximum matching and 3&lt;br /&gt;aditonal rules to solve ambiguities.&lt;br /&gt;&lt;br /&gt;For more information about the algorithm, please refer to the&lt;br /&gt;following essays:&lt;br /&gt;&lt;br /&gt;* &lt;a href="http://technology.chtsai.org/mmseg/"&gt;http://technology.chtsai.org/mmseg/&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://pluskid.lifegoo.com/?p=261"&gt;http://pluskid.lifegoo.com/?p=261&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;== CHANGES&lt;br /&gt;&lt;br /&gt;* Add cache to find_match_words: performance improved.&lt;br /&gt;* Implement Chunk as a module instead of a class: performance improved.&lt;br /&gt;* Don’t store unnecessary data in dictionary: memory usage reduced.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15313887-2989794361438400657?l=pluskid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pluskid.blogspot.com/feeds/2989794361438400657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15313887&amp;postID=2989794361438400657' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/2989794361438400657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/2989794361438400657'/><link rel='alternate' type='text/html' href='http://pluskid.blogspot.com/2008/02/ann-rmmseg-012-released.html' title='[ANN] RMMSeg 0.1.2 Released'/><author><name>pluskid</name><uri>http://www.blogger.com/profile/17997317415745134928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15313887.post-3379523591474307089</id><published>2008-01-05T08:14:00.000-08:00</published><updated>2008-01-05T08:20:29.700-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs ruby rspec'/><title type='text'>Running RSpec in Emacs</title><content type='html'>&lt;span style="font-size:78%;"&gt;This article is originally posted at my main blog (Mostly Chinese) : &lt;a href="http://pluskid.lifegoo.com/?p=245"&gt;http://pluskid.lifegoo.com/?p=245&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; is a Behaviour Driven Development framework for Ruby. It’s output format can be customized. However, the default format works well in Emacs’s &lt;code&gt;compilation-mode&lt;/code&gt;. Type &lt;code&gt;M-x compile&lt;/code&gt; and input &lt;code&gt;spec file_name_spec.rb&lt;/code&gt;. The result will be prompted at a new buffer.&lt;br /&gt;&lt;br /&gt;Some useful information are colorized. You can even use your mouse to click on the failures to go directly to the line where spec fails (Of course there’re shortcuts like &lt;code&gt;C-`&lt;/code&gt; available). However, we can still make it better.&lt;br /&gt;&lt;h3&gt;More highlighting&lt;/h3&gt;&lt;p&gt;By default the cursor is at the beginning in the newly prompted buffer with the &lt;code&gt;spec&lt;/code&gt; results. We want it to be at the end so that we can see how many examples failed. That’s easy, in fact, it is the default behavior before Emacs 20.3:&lt;/p&gt;  &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="lisp"&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;;; keep scrolling in compilation result buffer&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;setq&lt;/span&gt; compilation-scroll-output t&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;That’s simple and cool! But I want the number be highlighted! And &lt;b&gt;more&lt;/b&gt; highlighted when the number of failures is not zero. That’s also easy, we can add some rules to achieve this:&lt;/p&gt; &lt;p&gt;&lt;span id="more-245"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="lisp"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;add-to-&lt;span style="color: rgb(177, 177, 0);"&gt;list&lt;/span&gt; 'compilation-mode-font-lock-keywords&lt;br /&gt;      '&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"^&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;([[:digit:]]+&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;) examples?, &lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;([[:digit:]]+&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;) failures?&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;(?:, &lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;([[:digit:]]+&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;) pendings?&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;)?$"&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;0&lt;/span&gt; '&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;face &lt;span style="color: rgb(177, 177, 0);"&gt;nil&lt;/span&gt; message &lt;span style="color: rgb(177, 177, 0);"&gt;nil&lt;/span&gt; help-echo &lt;span style="color: rgb(177, 177, 0);"&gt;nil&lt;/span&gt; mouse-face &lt;span style="color: rgb(177, 177, 0);"&gt;nil&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt; t&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt; compilation-info-face&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;2&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;string= &lt;span style="color: rgb(255, 0, 0);"&gt;"0"&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;match-string &lt;span style="color: rgb(204, 102, 204);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;        compilation-info-face&lt;br /&gt;      compilation-error-face&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;3&lt;/span&gt; compilation-info-face t t&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;And here’s a screenshot:&lt;/p&gt; &lt;center&gt;&lt;img src="http://pluskid.lifegoo.com/wp-content/uploads/2008/01/emacs-rspec.png" alt="emacs-rspec.png" /&gt;&lt;/center&gt; &lt;p&gt;Yeah! Cool! &lt;img src="http://pluskid.lifegoo.com/wp-content/plugins/smilies-themer/adiumicons/biggrin.png" alt=":D" class="wp-smiley" /&gt; &lt;/p&gt; &lt;h3&gt;Smart Compile&lt;/h3&gt; &lt;p&gt;&lt;a href="http://www.emacswiki.org/cgi-bin/wiki?SmartCompile"&gt;smart-compile.el&lt;/a&gt; is an extension for Emacs to guess the compilation command for different type of files. Customization is simple. Here’s my customization (I use Emacs to edit a lot of files):&lt;/p&gt;  &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="lisp"&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;require 'smart-compile&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;setq&lt;/span&gt; smart-compile-alist&lt;br /&gt;     '&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"/programming/guile/.*c$"&lt;/span&gt; .    &lt;span style="color: rgb(255, 0, 0);"&gt;"gcc -Wall %f `guile-config link` -o %n"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;.c&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;'"&lt;/span&gt;              .       &lt;span style="color: rgb(255, 0, 0);"&gt;"gcc -Wall %f -lm -o %n"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;.[Cc]+[Pp]*&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;'"&lt;/span&gt;     .       &lt;span style="color: rgb(255, 0, 0);"&gt;"g++ -Wall %f -lm -o %n"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;.java$"&lt;/span&gt;             .       &lt;span style="color: rgb(255, 0, 0);"&gt;"javac %f"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"_spec&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;.rb$"&lt;/span&gt;          .       &lt;span style="color: rgb(255, 0, 0);"&gt;"spec %f"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;.rb$"&lt;/span&gt;               .       &lt;span style="color: rgb(255, 0, 0);"&gt;"ruby %f"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;emacs-lisp-mode        .       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;emacs-lisp-byte-compile&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;html-mode              .       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;browse-url-of-buffer&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;html-helper-mode       .       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;browse-url-of-buffer&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\\&lt;/span&gt;.skb$"&lt;/span&gt;              .       &lt;span style="color: rgb(255, 0, 0);"&gt;"skribe %f -o %n.html"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;haskell-mode           .       &lt;span style="color: rgb(255, 0, 0);"&gt;"ghc -o %n %f"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;asy-mode               .       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;call-interactively 'asy-compile-view&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;muse-mode              .       &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;call-interactively 'muse-project-publish&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;global-set-key &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;kbd &lt;span style="color: rgb(255, 0, 0);"&gt;"&lt;f9&gt;"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt; 'smart-compile&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;I set the global shortcut to &lt;code&gt;f9&lt;/code&gt;. Now just name your spec files with &lt;code&gt;foo_spec.rb&lt;/code&gt; (this is the convention). When you are in the buffer, just press &lt;code&gt;f9&lt;/code&gt;. It will prompt you the correct command to run your specs. &lt;/p&gt; &lt;p&gt;Wish you enjoy it! &lt;img src="http://pluskid.lifegoo.com/wp-content/plugins/smilies-themer/adiumicons/happy.png" alt=":)" class="wp-smiley" /&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15313887-3379523591474307089?l=pluskid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pluskid.blogspot.com/feeds/3379523591474307089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15313887&amp;postID=3379523591474307089' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/3379523591474307089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15313887/posts/default/3379523591474307089'/><link rel='alternate' type='text/html' href='http://pluskid.blogspot.com/2008/01/running-rspec-in-emacs.html' title='Running RSpec in Emacs'/><author><name>pluskid</name><uri>http://www.blogger.com/profile/17997317415745134928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
