<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[高見龍]]></title>
  <link href="http://blog.eddie.com.tw/atom.xml" rel="self"/>
  <link href="http://blog.eddie.com.tw/"/>
  <updated>2015-04-19T19:57:14+08:00</updated>
  <id>http://blog.eddie.com.tw/</id>
  <author>
    <name><![CDATA[高見龍]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Ruby 語法放大鏡之「有時候會看到有兩個冒號寫法是什麼意思?」]]></title>
    <link href="http://blog.eddie.com.tw/2015/04/19/namespace/"/>
    <updated>2015-04-19T18:09:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2015/04/19/namespace</id>
    <content type="html"><![CDATA[<p class="info">
「<a href="http://blog.eddie.com.tw/2014/12/28/ruby-for-rails/">Ruby 語法放大鏡</a>」系列短文主要是針對在大家學習 Ruby 或 Rails 時看到一些神奇但不知道用途的語法介紹，希望可以藉由這一系列的短文幫大家更容易的了解到底 Ruby 或 Rails 是怎麼回事。</p>


<p>隨便打開你 Rails 專案裡的 model 檔案，它可能會長得像這樣：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Post</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:user</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:category</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>第一行後面那個 <code>ActiveRecord::Base</code> 裡面的 2 個冒號 <code>::</code>，各位知道是什麼意思嗎?</p>

<h2>菜市場名</h2>

<p>也許你也叫金城武(或自己覺得自己長得像金城武)，然後我也剛好也很巧叫金城武，這樣在大街上大叫一聲帥哥就一堆人回頭了，不太好。</p>

<p>寫程式偶爾也會遇到這樣的狀況，舉例來說，如果大家剛好都有一個叫做 <code>Animal</code> 的類別或是 <code>Flyable</code> 的模組，放在同一個專案裡就會打架了。所以 Ruby 有設計 namespace 來解決這個問題。</p>

<p>在 Ruby 裡，因為 <code>module</code> 或 <code>class</code> 可以有巢狀結構(類別裡可以包模組，模組裡面可以包類別，就是大腸包小腸的概念啦)，剛好可以拿來做 namespace 的包裝，例如：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">module</span> <span class="nn">Utility</span>
</span><span class='line'>  <span class="k">module</span> <span class="nn">Flyable</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">fly</span>
</span><span class='line'>      <span class="c1"># ....</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>這樣一來，如果要使用 <code>Flyable</code> 這個類別的話：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Cat</span>
</span><span class='line'>  <span class="kp">include</span> <span class="no">Utility</span><span class="o">::</span><span class="no">Flyable</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>要 include 那個 Flyable 模組，就必須連名帶姓的 include，也就是「樹林::金城武」、「三重::劉德華」的概念。</p>

<p>除此之外，其實你也可把常數包在 namespace 裡：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">module</span> <span class="nn">Utility</span>
</span><span class='line'>  <span class="no">TaxRate</span> <span class="o">=</span> <span class="mi">10</span>
</span><span class='line'>  <span class="k">module</span> <span class="nn">Flyable</span>
</span><span class='line'>    <span class="no">Speed</span> <span class="o">=</span> <span class="mi">20</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">fly</span>
</span><span class='line'>      <span class="c1"># ....</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="nb">puts</span> <span class="no">Utility</span><span class="o">::</span><span class="no">TaxRate</span>          <span class="c1"># =&gt; 10</span>
</span><span class='line'><span class="nb">puts</span> <span class="no">Utility</span><span class="o">::</span><span class="no">Flyable</span><span class="o">::</span><span class="no">Speed</span>   <span class="c1"># =&gt; 20</span>
</span></code></pre></td></tr></table></div></figure>


<p>要使用這些常數，也是一樣要提供完整的路徑給才行。(如果你知道的話，其實不管是類別或模組，它們的名字基本上也就是常數而已)</p>

<p>所以，原來這段程式範例：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Post</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:user</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:category</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>它的意思就是說有一個叫做 <code>Post</code> 的類別，它是繼承自某個放在 <code>ActiveRecord</code> 的模組(或類別)裡的 <code>Base</code> 類別。如果去 github 上翻 Rails 的原始碼的話(<a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb" target="_blank">連結</a>)，應該可以看到這段：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">module</span> <span class="nn">ActiveRecord</span>
</span><span class='line'>  <span class="c1"># .....</span>
</span><span class='line'>  <span class="c1"># 中略</span>
</span><span class='line'>  <span class="c1"># .....</span>
</span><span class='line'>  <span class="k">class</span> <span class="nc">Base</span>
</span><span class='line'>    <span class="kp">extend</span> <span class="no">ActiveModel</span><span class="o">::</span><span class="no">Naming</span>
</span><span class='line'>    <span class="kp">extend</span> <span class="no">ActiveSupport</span><span class="o">::</span><span class="no">Benchmarkable</span>
</span><span class='line'>    <span class="kp">extend</span> <span class="no">ActiveSupport</span><span class="o">::</span><span class="no">DescendantsTracker</span>
</span><span class='line'>
</span><span class='line'>    <span class="kp">extend</span> <span class="no">ConnectionHandling</span>
</span><span class='line'>    <span class="kp">extend</span> <span class="no">QueryCache</span><span class="o">::</span><span class="no">ClassMethods</span>
</span><span class='line'>    <span class="c1"># ... 略</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>的確是有一個 <code>ActiveRecord</code> 的模組，裡面包了一個 <code>Base</code> 的類別沒錯 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby 語法放大鏡之「類別跟模組有什麼不一樣?」]]></title>
    <link href="http://blog.eddie.com.tw/2015/03/24/class-and-module/"/>
    <updated>2015-03-24T12:09:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2015/03/24/class-and-module</id>
    <content type="html"><![CDATA[<p class="info">
「<a href="http://blog.eddie.com.tw/2014/12/28/ruby-for-rails/">Ruby 語法放大鏡</a>」系列短文主要是針對在大家學習 Ruby 或 Rails 時看到一些神奇但不知道用途的語法介紹，希望可以藉由這一系列的短文幫大家更容易的了解到底 Ruby 或 Rails 是怎麼回事。</p>


<p>在網路上常看到一些介紹 Ruby 裡類別(class)跟模組(module)的差別，有人說他們兩個差別很大，是完全不同的東西。事實上，類別跟模組是很像的。可能很多人不知道，類別跟模組是有血緣關係的，如果你試著這樣做：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="nb">puts</span> <span class="no">Class</span><span class="o">.</span><span class="n">superclass</span>
</span></code></pre></td></tr></table></div></figure>


<p>你會得到 <code>Module</code> 這個類別。也就是說，在 Ruby 裡，「類別」其實就是「模組」的後代，類別根本就是繼承自模組來的。即然是同一個體系，自然沒有太多的差異。</p>

<h3>那差別是什麼?</h3>

<p>最明顯的差別，當然就是一個是用 <code>class</code> 來定義，一個是用 <code>module</code> 來定義。至於前、後代功能上的差別，我們只要寫幾行簡單的程式就可以看得出來：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="c1"># 前、後代的類別方法差異：</span>
</span><span class='line'><span class="nb">p</span> <span class="no">Class</span><span class="o">.</span><span class="n">methods</span> <span class="o">-</span> <span class="no">Module</span><span class="o">.</span><span class="n">methods</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 或直接這樣寫：</span>
</span><span class='line'><span class="nb">p</span> <span class="no">Class</span><span class="o">.</span><span class="n">methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>上面這段會得到 <code>[]</code> (空陣列)，表示他們在類別方法上並沒有差別。再來看看實體方法的差別：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="c1"># 前、後代的實體方法差異：</span>
</span><span class='line'><span class="nb">p</span> <span class="no">Class</span><span class="o">.</span><span class="n">instance_methods</span> <span class="o">-</span> <span class="no">Module</span><span class="o">.</span><span class="n">instance_methods</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 或直接這樣寫：</span>
</span><span class='line'><span class="nb">p</span> <span class="no">Class</span><span class="o">.</span><span class="n">instance_methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>會得到以下結果：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="o">[</span><span class="ss">:allocate</span><span class="p">,</span> <span class="ss">:new</span><span class="p">,</span> <span class="ss">:superclass</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>其中，<code>allocate</code> 跟 <code>new</code> 跟產生實體(instance)有關，<code>superclass</code> 跟繼承有關。</p>

<p>也就是說，類別比模組多了可以產生實體的能力以及繼承能力。</p>

<h3>那用途上有什麼差別?</h3>

<p>請大家先思考一個問題：「如果我有一個小貓類別，我希望這個小貓會飛，你會怎麼做?」</p>

<ol>
<li>直接寫一個有飛行功能的小鳥類別，然後再叫小貓類別去繼承它?</li>
<li>直接把飛行功能寫在小貓類別裡?</li>
</ol>


<p>第 1 種做法的設計有點怪怪的，好好的貓不當，為什麼要去當鳥? 為了想要有飛行功能就去當別人家的小孩&#8230;</p>

<p>第 2 種做法看來似乎可行，但如果之後又有個「我希望我的這個小狗類別也會飛!」的需求，那這樣又得在小狗類別裡寫一段飛行功能，程式碼沒辦法共同。</p>

<p>這時候，模組就可以派上用場了。</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">module</span> <span class="nn">Flyable</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">fly</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="s2">&quot;I can fly!&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Cat</span>
</span><span class='line'>  <span class="kp">include</span> <span class="no">Flyable</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">kitty</span> <span class="o">=</span> <span class="no">Cat</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="n">kitty</span><span class="o">.</span><span class="n">fly</span>        <span class="c1"># =&gt; I can fly!</span>
</span></code></pre></td></tr></table></div></figure>


<p>在上面這段範例中，我做了一個飛行模組(Flyable)，然後小貓類別不用特別寫什麼功能，就只要把這個飛行模組掛上去(include)就搞定了。</p>

<p>如果之後小狗類別也想要會飛的話，只要這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Dog</span>
</span><span class='line'>  <span class="kp">include</span> <span class="no">Flyable</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>小狗也會飛了。</p>

<h3>要用繼承還是要用模組?</h3>

<p>基本上，如果你發現你要做的這個功能，它可能在很多不同體系的類別裡都會用得到，那你可以考慮把功能包在模組裡，然後在必要的時候再 include 進來即可。</p>

<p>如果你還是不知道到底類別跟模組有什麼差別，我再舉二個例子。</p>

<p>不知道大家有沒看過<a href="http://zh.wikipedia.org/wiki/%E7%81%AB%E5%BD%B1%E5%BF%8D%E8%80%85">火影忍者</a>這部漫畫，漫畫裡的主人公之一，宇智波佐助，因為他們家族血統的關係，他寫輪眼這個功能是天生就有的，這個功能是從他的家族「繼承」來的。而佐助的老師，旗木卡卡西，他雖然也有寫輪眼功能，但他的寫輪眼並非繼承來的，事實上是他在年輕時候 include 了某個寫輪眼模組，所以才有這個效果。</p>

<p>另一個例子，<a href="http://zh.wikipedia.org/wiki/ONE_PIECE">海賊王</a>漫畫裡，魯夫本來是普通人，但在偶然的機會下，他 include 了橡膠果實之後，他就有了橡膠人的能力了，並不是因為他老爸是橡膠人所以他才是橡膠人。</p>

<p>以上，希望能讓大家在使用類別跟模組時有更進一步的認識 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby 語法放大鏡之「Ruby 的參數」]]></title>
    <link href="http://blog.eddie.com.tw/2015/03/22/parameters/"/>
    <updated>2015-03-22T12:09:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2015/03/22/parameters</id>
    <content type="html"><![CDATA[<p class="info">
「<a href="http://blog.eddie.com.tw/2014/12/28/ruby-for-rails/">Ruby 語法放大鏡</a>」系列短文主要是針對在大家學習 Ruby 或 Rails 時看到一些神奇但不知道用途的語法介紹，希望可以藉由這一系列的短文幫大家更容易的了解到底 Ruby 或 Rails 是怎麼回事。</p>


<p>大家在寫 Rails 專案的時候，一定都有用過 <code>link_to</code> 這個 view helper。問大家一個簡單的問題：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">link_to</span> <span class="s1">&#39;刪除&#39;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:delete</span><span class="p">,</span> <span class="ss">data</span><span class="p">:</span> <span class="p">{</span> <span class="ss">confirm</span><span class="p">:</span> <span class="s1">&#39;sure?&#39;</span> <span class="p">},</span> <span class="ss">class</span><span class="p">:</span><span class="s1">&#39;btn&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>請問，上面這段範例中，<code>link_to</code> 方法共有幾個參數?</p>

<p>如果你的答案是 5 個，那你就需要繼續往下看了 :)</p>

<p>在<a href="http://blog.eddie.com.tw/2015/03/21/attr_accessor/">這篇文章</a>中提到，Ruby 很愛省略東西，像是方法的小括號，所以原來上面的 <code>link_to</code> 語法：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">link_to</span> <span class="s1">&#39;刪除&#39;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:delete</span><span class="p">,</span> <span class="ss">data</span><span class="p">:</span> <span class="p">{</span> <span class="ss">confirm</span><span class="p">:</span> <span class="s1">&#39;sure?&#39;</span> <span class="p">},</span> <span class="ss">class</span><span class="p">:</span><span class="s1">&#39;btn&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>原本應該長這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">link_to</span><span class="p">(</span><span class="s1">&#39;刪除&#39;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:delete</span><span class="p">,</span> <span class="ss">data</span><span class="p">:</span> <span class="p">{</span> <span class="ss">confirm</span><span class="p">:</span> <span class="s1">&#39;sure?&#39;</span> <span class="p">},</span> <span class="ss">class</span><span class="p">:</span><span class="s1">&#39;btn&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<h3>最後一個參數如果是 Hash，大括號可省略</h3>

<p>在 Ruby 省略小括號大家都知道，不過逗點分開的參數不是 5 個嗎?</p>

<p>事實上，在 Ruby 中如果最後一個參數是 Hash 的話，它的大括號是可以省略的。舉個例子來說：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">def</span> <span class="nf">say_hello_to</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="n">options</span> <span class="o">=</span> <span class="p">{})</span>
</span><span class='line'>  <span class="c1"># do something</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>如果要使用這個方法，可以這樣寫：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">say_hello_to</span> <span class="s2">&quot;eddie&quot;</span><span class="p">,</span> <span class="p">{</span><span class="ss">age</span><span class="p">:</span> <span class="mi">18</span><span class="p">,</span> <span class="ss">favorite</span><span class="p">:</span> <span class="s1">&#39;ruby&#39;</span><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>又，因為最後一個參數是 Hash，所以 Hash 的大括號也可省略：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">say_hello_to</span> <span class="s2">&quot;eddie&quot;</span><span class="p">,</span> <span class="ss">age</span><span class="p">:</span> <span class="mi">18</span><span class="p">,</span> <span class="ss">favorite</span><span class="p">:</span> <span class="s1">&#39;ruby&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>如果你了解有什麼東西被省略的話，一開始的那段 link_to 的範例：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">link_to</span> <span class="s1">&#39;刪除&#39;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:delete</span><span class="p">,</span> <span class="ss">data</span><span class="p">:</span> <span class="p">{</span> <span class="ss">confirm</span><span class="p">:</span> <span class="s1">&#39;sure?&#39;</span> <span class="p">},</span> <span class="ss">class</span><span class="p">:</span><span class="s1">&#39;btn&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>還原之後會變成：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">link_to</span><span class="p">(</span><span class="s1">&#39;刪除&#39;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="p">{</span><span class="nb">method</span><span class="p">:</span> <span class="ss">:delete</span><span class="p">,</span> <span class="ss">data</span><span class="p">:</span> <span class="p">{</span> <span class="ss">confirm</span><span class="p">:</span> <span class="s1">&#39;sure?&#39;</span> <span class="p">},</span> <span class="ss">class</span><span class="p">:</span><span class="s1">&#39;btn&#39;</span><span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p>所以，其實參數個數只有 3 個，最後一個參數是一個 Hash。</p>

<h3>小結</h3>

<p>Ruby 的語法可以適時的省略小括號、大括號或 return，程式碼寫起來的確會更像文章，對新手來說可能會容易混淆，不過看久了應該也會慢慢習慣了。</p>

<p>以上，希望對大家有幫助 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby 語法放大鏡之「attr_accessor 是幹嘛的?」]]></title>
    <link href="http://blog.eddie.com.tw/2015/03/21/attr_accessor/"/>
    <updated>2015-03-21T12:09:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2015/03/21/attr_accessor</id>
    <content type="html"><![CDATA[<p class="info">
「<a href="http://blog.eddie.com.tw/2014/12/28/ruby-for-rails/">Ruby 語法放大鏡</a>」系列短文主要是針對在大家學習 Ruby 或 Rails 時看到一些神奇但不知道用途的語法介紹，希望可以藉由這一系列的短文幫大家更容易的了解到底 Ruby 或 Rails 是怎麼回事。</p>


<p>先說結論：</p>

<blockquote><p>attr_accessor 會幫你在 Ruby 的類別裡產生一對 getter 以及 setter 方法。</p></blockquote>


<p>不過我想這結論對新手來說有講跟沒講一樣，讓我們繼續往下看。</p>

<p>跟別的程式語言比起來，Ruby 可以省略很多東西，像是呼叫方法的時候可以不用小括號，回傳資料的時候有時候不用特別加 <code>return</code>。</p>

<p>我們先來看一段範例：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Girl</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">age</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">mary</span> <span class="o">=</span> <span class="no">Girl</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>這是一個簡單的 Ruby 類別，我用 <code>Girl</code> 類別建一個名為 <code>mary</code> 的實體(instance)，並且在初始化的時候就設定她的年紀為 20。<code>Girl</code> 類別裡有一個 <code>@age</code> 這個實體變數(instance variable)，也許你會猜說如果要知道 <code>mary</code> 的年紀的話，只要：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="nb">puts</span> <span class="n">mary</span><span class="o">.</span><span class="n">age</span>
</span></code></pre></td></tr></table></div></figure>


<p>就行了，但一執行就會發現錯誤訊息：</p>

<pre><code>undefined method `age' for #&lt;Girl:0x007f93a609fa10 @age=20&gt; (NoMethodError)
</code></pre>

<p>怪了，我是想要存取 <code>age</code> 這個屬性，為什麼錯誤訊息卻是 <code>undefined method</code>?</p>

<p>在解釋之前，要先說明幾個 Ruby 這個程式語言跟別家程式語言在設計上的不同：</p>

<h3>一、Ruby 的方法呼叫，常常會適時的省略小括號：</h3>

<p>舉個例子來說：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">def</span> <span class="nf">say_hi_to</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;hi, </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">say_hi_to</span><span class="p">(</span><span class="s2">&quot;eddie&quot;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>但我們通常會寫成：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">say_hi_to</span> <span class="s2">&quot;eddie&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>在呼叫方法的時候省略小括號，這在 Ruby 是很常見的寫法。</p>

<h3>二、Ruby 並沒有「屬性」(property/attribute)這樣的東西：</h3>

<p>雖然 <code>mary</code> 看起來有一個 <code>@age</code> 實體變數，但不表示是可以直接存取的屬性。硬是要用 <code>mary.age</code> 問她年紀，或是要用 <code>mary.age = 18</code> 來設定她的年紀，她都會賞你一巴掌，給你錯誤訊息的。</p>

<p><code>mary.age</code> 你以為是讀取 mary 上的 age 屬性，但事實上是在執行 <code>mary.age()</code> 方法，只是小括號被省略了。<code>mary.age=18</code> 你以為是設定 mary 的 age 屬性，但事實上是執行 <code>mary.age=(18)</code> 方法，只是小括號被省略了。</p>

<p>在 Ruby 裡，很多東西都跟你看到的不太一樣，例如，你以為 <code>1 + 2</code> 是簡單的數學運算嗎? 其實它是 <code>1.+(2)</code>，它是對數字物件 1 送了一個 <code>+</code> 的訊息，並且把數字物件 2 當做參數傳給它。</p>

<p>好啦，即然知道它們都是方法，那要怎麼定義它們呢?</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Girl</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">age</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">age</span>
</span><span class='line'>    <span class="k">return</span> <span class="vi">@age</span>  <span class="c1"># 這個 return 通常會省略</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">age</span><span class="o">=</span><span class="p">(</span><span class="n">new_age</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@age</span> <span class="o">=</span> <span class="n">new_age</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>上面這段範例中，第 6 ~ 8 行的方法會回傳 <code>@age</code>，又常稱之 getter；第 10 ~ 12 行的方法它會設定 <code>@age</code> 的值，故又常稱之 setter。</p>

<p>不過&#8230;等一下! 為什麼方法後面有個等號?</p>

<p>請把等號當做一般的字母看待。在 Ruby 定義方法的時候，等號跟其它字元一樣都可以是方法名字的一部份，只是這個特殊字元必須要放在方法名稱的結尾(其實包括問號跟驚嘆號也都一樣)。</p>

<p>這個方法就叫做 <code>age=</code>，要使用它就是用 <code>age=(18)</code>，沒錯，就是連等號一起呼叫它。所以，其實標準形態應該長這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">mary</span><span class="o">.</span><span class="n">age</span><span class="o">=</span><span class="p">(</span><span class="mi">18</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>又，因為前面提到，Ruby 可以省略小括號，所以可寫成：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">mary</span><span class="o">.</span><span class="n">age</span><span class="o">=</span><span class="mi">18</span>
</span></code></pre></td></tr></table></div></figure>


<p>然後，Ruby 又有幫忙加了一些語法糖衣，讓你在中間加一些空白字元也是可以的：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">mary</span><span class="o">.</span><span class="n">age</span> <span class="o">=</span> <span class="mi">18</span>
</span></code></pre></td></tr></table></div></figure>


<p>最後就會讓你看起來像是在設定 age 屬性了。</p>

<h2>這&#8230;會不會太麻煩了點?</h2>

<p>照這樣說，如果每次想要用類似的屬性寫法，就必須要寫一對方法來回傳、設定，會不會有點太麻煩啊。</p>

<p>是的，就是要這麼麻煩。不過請放心，工程師都很懶的，所以有另外設計了幾個方法可以讓你快速的產生前面提到的 getter/setter。</p>

<p>如果你的 getter/setter 很單純，就只是有回傳、設定實體變數的話，那你可用 Ruby 內建的幾個方法：<code>attr_reader</code>、<code>attr_writer</code> 以及 <code>attr_accessor</code>：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Girl</span>
</span><span class='line'>  <span class="kp">attr_accessor</span> <span class="ss">:age</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">age</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">mary</span> <span class="o">=</span> <span class="no">Girl</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">mary</span><span class="o">.</span><span class="n">age</span>    <span class="c1">#=&gt; 20</span>
</span><span class='line'><span class="n">mary</span><span class="o">.</span><span class="n">age</span> <span class="o">=</span> <span class="mi">18</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">mary</span><span class="o">.</span><span class="n">age</span>    <span class="c1">#=&gt; 18</span>
</span></code></pre></td></tr></table></div></figure>


<p>其中，<code>attr_reader</code> 只會幫你產生 getter，<code>attr_writer</code> 只會幫你產生 setter，而 <code>attr_accessor</code> 則會幫你產生 getter 及 setter。如果不相信，可以執行下面這行看一下：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="nb">p</span> <span class="no">Girl</span><span class="o">.</span><span class="n">instance_methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>應該會看到以下結果：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="o">[</span><span class="ss">:age</span><span class="p">,</span> <span class="ss">:age</span><span class="o">=]</span>
</span></code></pre></td></tr></table></div></figure>


<p>的確是產生了兩個方法，分別是 <code>age</code> 以及 <code>age=</code>。</p>

<h3>用了 attr_accessor 還能自己寫 getter 或 setter 嗎?</h3>

<p>當然是可以的，例如：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Girl</span>
</span><span class='line'>  <span class="kp">attr_accessor</span> <span class="ss">:age</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">age</span><span class="o">=</span><span class="p">(</span><span class="n">new_age</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@age</span> <span class="o">=</span> <span class="p">(</span><span class="n">new_age</span> <span class="o">&gt;</span> <span class="mi">18</span><span class="p">)</span> <span class="p">?</span> <span class="mi">18</span> <span class="p">:</span> <span class="n">new_age</span>  <span class="c1"># 如果大於 18，就只設定 18..</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">mary</span> <span class="o">=</span> <span class="no">Girl</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="n">mary</span><span class="o">.</span><span class="n">age</span> <span class="o">=</span> <span class="mi">30</span>     <span class="c1"># 即使設定為 30 歲...</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">mary</span><span class="o">.</span><span class="n">age</span>     <span class="c1"># 還是會永保 18 歲 :)</span>
</span></code></pre></td></tr></table></div></figure>


<p>因為你重新定義了 <code>age=</code> 方法，在執行的時候 Ruby 會跳出來跟你碎碎唸說 <code>warning: method redefined; discarding old age=</code>，但程式還是可執行。</p>

<p>所以，如果你只是想要客制化自己的 getter 或 setter 的話，可將 <code>attr_accessor</code> 改為 <code>attr_reader</code> 或 <code>attr_writer</code>，就不會有這個警告訊息了。</p>

<p>以上，希望對大家有幫助 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[新年新希望之誠徵 iOS app 開發學徒]]></title>
    <link href="http://blog.eddie.com.tw/2015/01/19/ios-apprentice-wanted/"/>
    <updated>2015-01-19T14:09:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2015/01/19/ios-apprentice-wanted</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2015/apprentice.jpg" alt="image" />
photo by <a href="https://www.flickr.com/photos/joceykinghorn/" target="_blank">Jocelyn Kinghorn</a></p>

<p>大概兩年前舉辦了一次「<a href="http://blog.eddie.com.tw/2013/02/08/new-rubyist-wanted/">徵求 Ruby/Rails 有心人</a>」活動，感謝大家不嫌棄，不過因為人數太多，最後變成了<a href="http://blog.eddie.com.tw/2013/04/22/1st-ruby-and-rails-training-course/">社群活動</a>了 XD</p>

<p>最近再度因為手邊的 iOS 案件在持續增加中(同時也有 Rails 的專案同時在進行)，與其要直接找現成的即戰力，不如趁這個機會自己從頭開始帶，雖然會比較辛苦、花時間，但一些開發的習慣可以從一開始就先養成好像也不錯，剛好順便練一下之前準備的 iOS/Swift 教材。</p>

<p>所以我又厚臉皮的想要來徵看看有沒有人願意來給我當學徒。</p>

<h2>你可能會學到什麼</h2>

<ul>
<li>iOS app 開發</li>
<li>Objective-C / Swift</li>
<li>Git</li>
<li><del>還有最重要的，可以一起組隊打 D3.. XD</del></li>
</ul>


<h2>權利義務</h2>

<p>基本上不會有什麼特別的權利義務，也不會有什麼學費或薪水。 其實我個人的私心，是希望學成之後可以有能力幫我消化或維護我手邊的專案。<del>這樣我這樣才有更多時間打 D3</del>。或是最後就直接加入<a href="http://5xruby.tw/">我們的團隊</a>接手客戶的專案，當然，如果開始接手專案的話就是一份正式的工作了，自然就會開始有薪水了，至於待遇會不會超過 22K? 我想應該不會太難 :)</p>

<h2>基本條件</h2>

<ul>
<li>男女不拘，但基於我已經有兩個小朋友了，所以還是男性佳。<del>女性佳我回家就要跪主機板了</del> (男性需役畢或免役)</li>
<li>最好是從學校畢業畢業不久或是已工作一、二年。</li>
<li>對寫程式有熱忱，不需要非常熟悉某種程式語言，但至少需要知道這個世界上不是只有 IE 這種瀏覽器。</li>
<li>需要自備 Mac 電腦(iPhone 或 iPad 可能也會需要)。</li>
<li>最好人是在北部。</li>
</ul>


<h2>人數限制</h2>

<p>最多三位，再多我可能就沒辦法顧到品質了。</p>

<h2>地點</h2>

<p><a href="http://5xruby.tw">五倍紅寶石</a> (台北車站附近)</p>

<h2>時間</h2>

<p>預計從三月份開始，每週找兩個晚上或週末的時間來練功(暫定)。</p>

<p>我不敢說自己是什麼大咖，但至少教大家如何寫 iOS app 來混口飯吃沒太大問題。 如果您有興趣，也覺得自己不會來個兩次就不來的，請點選以下的連結，並請簡單的介紹一下你自己。(預計會在農曆年前回覆錄取人選)</p>

<p>報名連結：<a href="http://5xruby.kktix.cc/events/ios-apprentice" target="_blank">http://5xruby.kktix.cc/events/ios-apprentice</a></p>

<p>感謝大家，先預祝大家新年都很快樂!</p>

<h2>工商服務</h2>

<p>順便偷渡幫忙宣傳一下我們自己最近開的課程資訊：</p>

<ul>
<li><a href="http://5xruby.tw/talks/rails-from-scratch" target="_blank">Ruby on Rails 從零開始</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby 語法放大鏡]]></title>
    <link href="http://blog.eddie.com.tw/2014/12/28/ruby-for-rails/"/>
    <updated>2014-12-28T14:35:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/12/28/ruby-for-rails</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2014/magnifying_glass.jpg" alt="image" />
photo by <a href="https://www.flickr.com/photos/puuikibeach/">davidd</a></p>

<p>大家在學習 Ruby 或 Ruby on Rails(以下簡稱 Rails)的時候，難免會有一些看不懂或是有一些不知道怎麼來的神奇語法，希望可以藉由這一系列的短文幫大家更容易的了解到底 Ruby/Rails 是怎麼回事。</p>

<p>預計會有以下的文章(持續更新中)：</p>

<h2>Ruby 相關：</h2>

<ol>
<li><a href="http://blog.eddie.com.tw/2015/03/21/attr_accessor/">attr_accessor 是幹嘛的?</a></li>
<li><a href="http://blog.eddie.com.tw/2015/03/24/class-and-module/">類別跟模組有什麼不一樣?</a></li>
<li><a href="http://blog.eddie.com.tw/2015/04/19/namespace/">有時候會看到有兩個冒號寫法(例如 ActiveRecord::Base)它是什麼意思?</a></li>
<li>為什麼 Hash 好像有不同的寫法?</li>
<li>有的變數變前面有一個冒號(例如 :name)，是什麼意思?</li>
<li>有的變數前面有 @ 符號(例如  @users )，這是什麼意思?</li>
<li>你知道 <code>require</code> 這個語法幫你做了什麼事嗎?</li>
<li><code>gem install</code> 之後，那些 gem 安裝到哪裡去了?</li>
<li>想要學 Ruby 該看哪些書?</li>
</ol>


<h2>Rails 相關</h2>

<ol>
<li><a href="http://blog.eddie.com.tw/2015/03/22/parameters/">為什麼 link_to 這個 view helper 的參數個數可長可短?</a></li>
<li>在 Rails 專案中，有個檔案叫 <code>schema.rb</code>，它是做什麼的?</li>
<li>有一個 Gemfile 了，為什麼還有個 Gemfile.lock? 這個檔案是幹嘛的?</li>
<li>常有時候會需要在指令面前加上 <code>bundle exec</code>，這有加沒加有什麼分別?</li>
<li>為什麼 <code>2.days.ago</code> 在內建的 irb 會找不到這個方法? 這不是 Ruby 語法嗎?</li>
<li>常在終端機裡下 <code>rake db:migrate</code> 指令，這個 <code>rake</code> 是什麼，後面那個 <code>db:migrate</code> 又是怎麼回事?</li>
<li>Strong Parameters 是什麼用途?</li>
<li>自己寫了一些的 view helper，有辦法也在 controller 裡使用嗎?</li>
<li>常在 controller 裡使用 <code>before_action</code>，它是一個方法嗎? 跟一般我們用 def 定義的有何不同?</li>
<li>在 application controller 裡看到的 <code>protect_from_forgery</code> 是什麼?</li>
<li>為什麼 model class 看起來空空的，但怎麼有那麼多好用的方法?</li>
<li>在 Gemfile 裡看到 <code>gem 'sass-rails', '~&gt; 4.0.3'</code> 或是 <code>gem 'uglifier', '&gt;= 1.3.0'</code> 這樣的寫法，那個 <code>~&gt;</code> 跟 <code>&gt;=</code> 各是代表什麼意思?</li>
<li>想要學 Rails 該看哪些書?</li>
</ol>


<p>以上，有的是關於 Ruby 的，有的是關於 Rails 的(嚴格說來其實都是 Ruby 的問題)
如果想到還有其它的會再繼續補充，或是大家有什麼想要知道也可以直接來信討論或是在本篇底下留言 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Private Setter in Ruby]]></title>
    <link href="http://blog.eddie.com.tw/2014/10/22/private-setter-in-ruby/"/>
    <updated>2014-10-22T14:35:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/10/22/private-setter-in-ruby</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2014/private_no_entry.jpg" alt="image" />
photo by <a href="https://www.flickr.com/photos/bradhigham/">Brad Higham</a></p>

<p>之前在 <a href="http://blog.eddie.com.tw/2011/07/26/public-protected-and-private-method-in-ruby/">Public, Protected and Private Method in Ruby</a> 這篇文章提到，在 Ruby 裡使用 private 方法的時候，不能明確的指出 receiver，以下面這段範例來說：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Dog</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">hello</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">gossip</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="kp">private</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">gossip</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="s2">&quot;don&#39;t tell anyone!&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">snoopy</span> <span class="o">=</span> <span class="no">Dog</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="n">snoopy</span><span class="o">.</span><span class="n">hello</span>        <span class="c1"># =&gt; NoMethodError</span>
</span><span class='line'><span class="n">snoopy</span><span class="o">.</span><span class="n">gossip</span>       <span class="c1"># =&gt; NoMethodError</span>
</span></code></pre></td></tr></table></div></figure>


<p>在上面這段程式碼的第 13 行，因為它明確的指出 receiver (snoopy)，所以執行這行程式碼會出現會出現 <code>NoMethodError</code> 的錯誤；而在第 3 行，即使 receiver 是 <code>self</code> 也一樣是不行的。</p>

<p>這是在 Ruby 裡面 private 方法的設計。</p>

<p>不過，今天剛好有朋友拿了一段程式碼給我看，才發現原來上面這個規則原來也是有例外的，舉個例子來說：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Dog</span>
</span><span class='line'>  <span class="kp">attr_accessor</span> <span class="ss">:name</span>
</span><span class='line'>  <span class="kp">private</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:name</span><span class="o">=</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">hello</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">gossip</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">greeting1</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">name</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">greeting2</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Snoopy&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="kp">private</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">gossip</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="s2">&quot;don&#39;t tell anyone!&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">snoopy</span> <span class="o">=</span> <span class="no">Dog</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="n">snoopy</span><span class="o">.</span><span class="n">hello</span>         <span class="c1"># =&gt; NoMethodError</span>
</span><span class='line'><span class="n">snoopy</span><span class="o">.</span><span class="n">gossip</span>        <span class="c1"># =&gt; NoMethodError</span>
</span><span class='line'><span class="n">snoopy</span><span class="o">.</span><span class="n">greeting1</span>     <span class="c1"># =&gt; NoMethodError</span>
</span><span class='line'><span class="n">snoopy</span><span class="o">.</span><span class="n">greeting2</span>     <span class="c1"># =&gt; It Works!</span>
</span></code></pre></td></tr></table></div></figure>


<p>在上面這段範例中用 <code>attr_accessor</code> 做了一個 <code>name</code> 的 getter 跟 setter，並且把 getter/setter 設定成 private。在第 10 行的地方呼叫了 private 的 getter，並且明確的指出 receiver 是 <code>self</code>，照規則來說會出現錯誤不意外，但第 14 行用類似的方法呼叫了 private 的 setter 卻沒有出錯!</p>

<p>的確 private 方法不能指出明確的 receiver，但 setter 算是這個規則的例外。因為你不在前面加 self 的話，像這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="k">def</span> <span class="nf">greeting</span>
</span><span class='line'>    <span class="nb">name</span> <span class="o">=</span> <span class="s2">&quot;Snoopy&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>這樣這個 <code>name</code> 不就變成區域變數的賦值了嗎?</p>

<p>想想看，如果在這裡呼叫 setter 不加 self 的話，那 Ruby 要怎麼分辨到底你是要呼叫 setter 還是區域變數?</p>

<p>話說回來，通常我們也不會沒事把 getter/setter 設定成 private，因為即然都做了 getter/setter 就是要給別人用的不是嗎? :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby 也可這樣寫]]></title>
    <link href="http://blog.eddie.com.tw/2014/10/16/happy-programming-ruby/"/>
    <updated>2014-10-16T14:35:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/10/16/happy-programming-ruby</id>
    <content type="html"><![CDATA[<p>很榮幸有機會能受邀參加 Livehouse.in 舉辦的 <a href="https://event.livehouse.in/2014/combo8/">Combo! 8 週連擊</a> 活動，本次的講題是「<a href="https://speakerdeck.com/eddie/happy-programming-ruby" target="_blank">Ruby 也可這樣寫</a>」，主要是來聊聊一些 Ruby 有趣(或奇怪)的語法，以及可以用 Ruby 做些什麼事 (without Rails)。</p>

<p><a href="https://speakerdeck.com/eddie/happy-programming-ruby" target="_blank"><img src="http://blog.eddie.com.tw/images/2014/slide_happy_ruby_programming.jpg" alt="image" /></a>
投影片連結：<a href="https://speakerdeck.com/eddie/happy-programming-ruby">https://speakerdeck.com/eddie/happy-programming-ruby</a></p>

<p>這並不是什麼新的主題，也不是很艱深的內容，只是發現最近在接手一些別人寫的 Ruby on Rails (以下簡稱 Rails)專案時發現，似乎不少人並不清楚 Ruby 一些特有的寫法，把 Ruby/Rails 當做 PHP 在寫，所以就想來試著介紹這個主題給大家，讓大家可以多認識一些 Ruby。</p>

<p>曾經寫過 Rails 的朋友也許寫過以下的語法來取得兩天前的時間：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="mi">2</span><span class="o">.</span><span class="n">days</span><span class="o">.</span><span class="n">ago</span>
</span></code></pre></td></tr></table></div></figure>


<p>很多人以為這是 Ruby 的語法，但如果你打開 irb 這樣寫卻會出現 <code>undefined method 'days' for 2:Fixnum</code> 的錯誤訊息，那是因為其實不管是 <code>days</code> 或是 <code>ago</code> 方法，都不是內建在 <code>Fixnum</code> 類別的方法，而是 Rails(更精準說的話應該是 ActiveSupport 這個 gem) 透過 Open Class 的手法在原本內建的 <code>Fixnum</code> 類別加上了這些便利的方法。</p>

<p>我想大家都不否認 Ruby 的確是被 Rails 給帶紅起來的，不過一位日本的 Ruby 大前輩前田修吾在他的一份簡報「<a href="http://shugo.net/tmp/rails-syndrome.pdf" target="_blank">Rails 症候群の研究</a>」提到「Ruby が何かわかっていない」(中譯：不知道 Ruby 是什麼東西)，其實也是有點讓人擔心 XD。</p>

<h2>Ruby 是什麼?</h2>

<p><a href="http://ruby-lang.org">Ruby</a> 是一種電腦程式語言，而 Rails 是一種使用 Ruby 建構出來的網站開發框架 (Web Framework)，但 Rails 不是一種電腦程式語言。(當然要說 Rails 這樣的 DSL 也是一種語言也是 ok 的)</p>

<p>Ruby 是一種物件導向的程式語言，在 Ruby 裡的所有東西都是物件(幾乎)，包括數字 5 也是，它是一個數字物件，所以我們在 Ruby 可以寫出像下面這樣的程式碼：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="mi">5</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="s2">&quot;Hello, Ruby&quot;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>聽說&#8230;</h2>

<h3>聽說 Ruby 很慢!</h3>

<p>這個嘛，就要看跟誰比了，跟 C 語言比的話當然是一定慢的，但 Ruby 還沒有慢到不能用的地步(而且通常網站慢的地方都不是 Ruby 本身)。慢的地方如果真的很介意，也可改用其它方式來改善(例如改寫成 Extension)</p>

<p>曾經有朋友拿 Twitter 拋棄 Rails 而改用 Scala 為例說「你看看連 Twitter 都嫌 Rails 慢了!」，的確 Rails 並不是執行效率非常好的框架，但是回頭想想，貴單位的網站的用戶或流量做得到 Twitter 的 1% 嗎? 網站還沒做出來就先擔心撐不撐得住大流量可能也擔心得太早了一點 XD</p>

<p>PS:事實上現在 Twitter 的前端也還是用 Rails 在開發。</p>

<h3>聽說寫 Ruby 要先買 Mac?</h3>

<p>不知道從什麼時候開始開始流傳著「要寫 Ruby/Rails 要先買 Mac」這樣的都市傳說，特別是在 Ruby 相關的聚會活動或研討會，大家擺在桌上的幾乎是清一色的 Mac 筆電。其實開發 Ruby/Rails 專案真正合適的應該是 Linux/Ubuntu 的環境，畢竟最後的專案是佈署在這些平台上，而不是在你的 Mac 筆電裡。</p>

<p>那為什麼越來越多開發者都買了 Mac? 我想主要原因除了看起來比較潮之外，就是 Mac OS 本質上其實是 BSD 系統，它有內建的 terminal(或說是 shell) 可以用，對寫 Ruby/Rails 的開發者來說是很方便的。</p>

<h2>Ruby 可以這樣寫</h2>

<h3>if modifier</h3>

<p>以下是個很單純的 if 判斷：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">age</span> <span class="o">=</span> <span class="mi">18</span>
</span><span class='line'><span class="k">if</span> <span class="n">age</span> <span class="o">&gt;</span> <span class="mi">18</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;OK, I can see this movie&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>在 Ruby 裡，像這樣單純的 if 判斷，我通常會把 if 放到後面，讓整個句字看起來更像一般的英文口語：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">age</span> <span class="o">=</span> <span class="mi">18</span>
</span><span class='line'><span class="nb">puts</span> <span class="s2">&quot;OK, I can see this movie&quot;</span> <span class="k">if</span> <span class="n">age</span> <span class="o">&gt;</span> <span class="mi">18</span>
</span></code></pre></td></tr></table></div></figure>


<h3>if..else.., case..when..</h3>

<p>如果您曾經寫過其它程式語言，對以下的語法應該不陌生：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">age</span> <span class="o">=</span> <span class="mi">16</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">age</span> <span class="o">&lt;</span> <span class="mi">3</span> <span class="k">then</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Baby&quot;</span>
</span><span class='line'><span class="k">elsif</span> <span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">3</span> <span class="o">&amp;&amp;</span> <span class="n">age</span> <span class="o">&lt;</span> <span class="mi">10</span> <span class="k">then</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Kids&quot;</span>
</span><span class='line'><span class="k">elsif</span> <span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">10</span> <span class="o">&amp;&amp;</span> <span class="n">age</span> <span class="o">&lt;</span> <span class="mi">18</span> <span class="k">then</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Teenager&quot;</span>
</span><span class='line'><span class="k">else</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Oh Yeah!&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>就是一連串的 <code>if..else..</code> 啦，這樣的寫法沒有錯，也可以正常執行，但教課書通常會教說如果看到很多的 else if 的話，可考慮用 <code>case..when</code> 來處理：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">age</span> <span class="o">=</span> <span class="mi">16</span>
</span><span class='line'>
</span><span class='line'><span class="k">case</span>
</span><span class='line'><span class="k">when</span> <span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">age</span> <span class="o">&lt;</span> <span class="mi">3</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Baby&quot;</span>
</span><span class='line'><span class="k">when</span> <span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">3</span> <span class="o">&amp;&amp;</span> <span class="n">age</span> <span class="o">&lt;</span> <span class="mi">10</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Kids&quot;</span>
</span><span class='line'><span class="k">when</span> <span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">10</span> <span class="o">&amp;&amp;</span> <span class="n">age</span> <span class="o">&lt;</span> <span class="mi">18</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Teenager&quot;</span>
</span><span class='line'><span class="k">else</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Oh Yeah!&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>但中間那段大於小於的比較，我會喜歡用 Ruby 裡內建的 Range 來比對，看起來會更容易懂：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">age</span> <span class="o">=</span> <span class="mi">16</span>
</span><span class='line'>
</span><span class='line'><span class="k">case</span> <span class="n">age</span>
</span><span class='line'><span class="k">when</span> <span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">3</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Baby&quot;</span>
</span><span class='line'><span class="k">when</span> <span class="mi">3</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">10</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Kids&quot;</span>
</span><span class='line'><span class="k">when</span> <span class="mi">10</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">18</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Teenager&quot;</span>
</span><span class='line'><span class="k">else</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Oh Yeah!&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>multiple assignment</h3>

<p>在 Ruby 可以一口氣指定好幾個變數的值：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span>
</span></code></pre></td></tr></table></div></figure>


<p>只要一行就可達到三行的效果。</p>

<p>在其它程式語言，如果想要交換 x 跟 y 兩個變數的值，通常會這樣做：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">x</span> <span class="o">=</span> <span class="mi">1</span>
</span><span class='line'><span class="n">y</span> <span class="o">=</span> <span class="mi">2</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 交換 x, y 的值</span>
</span><span class='line'><span class="n">tmp</span> <span class="o">=</span> <span class="n">x</span>
</span><span class='line'><span class="n">x</span> <span class="o">=</span> <span class="n">y</span>
</span><span class='line'><span class="n">y</span> <span class="o">=</span> <span class="n">tmp</span>
</span></code></pre></td></tr></table></div></figure>


<p>但在 Ruby 可以利用上面提到的變數多重指定的特性改寫成這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">x</span> <span class="o">=</span> <span class="mi">1</span>
</span><span class='line'><span class="n">y</span> <span class="o">=</span> <span class="mi">2</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 交換 x, y 的值</span>
</span><span class='line'><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span>
</span></code></pre></td></tr></table></div></figure>


<p>相當簡單又容易懂。</p>

<h3>unnecessary return</h3>

<p>以下是我在之前某個 Rails 專案裡面看到的一段程式碼：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">def</span> <span class="nf">is_even</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
</span><span class='line'>  <span class="k">if</span> <span class="n">n</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span>
</span><span class='line'>    <span class="k">return</span> <span class="kp">true</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>    <span class="k">return</span> <span class="kp">false</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>這樣寫沒問題，只是一看就猜得出來可能是剛從別的程式語言轉過來沒多久。在 Ruby 裡的 return 並不是一定要寫的，所以上式再透過三元運算子的簡化可以變這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">def</span> <span class="nf">is_even</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
</span><span class='line'>  <span class="p">(</span><span class="n">n</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">?</span> <span class="kp">true</span> <span class="p">:</span> <span class="kp">false</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>或可再精簡一些：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">def</span> <span class="nf">is_even</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
</span><span class='line'>  <span class="n">n</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>事實上，如果再熟悉 Ruby 一點的話就會發現其實數字類別本身就有帶一個判斷偶數或奇數的方法：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="nb">puts</span> <span class="mi">2</span><span class="o">.</span><span class="n">even?</span>  <span class="c1"># =&gt; true</span>
</span><span class='line'><span class="nb">puts</span> <span class="mi">4</span><span class="o">.</span><span class="n">odd?</span>   <span class="c1"># =&gt; false</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Open Class</h3>

<p>Ruby 的 Open Class 可以讓開發者任意的幫已存在的類別(甚至是內建類別)加功能，例如：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">String</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">say_hello</span>
</span><span class='line'>    <span class="s2">&quot;Hello, </span><span class="si">#{</span><span class="nb">self</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="nb">puts</span> <span class="s2">&quot;Ruby&quot;</span><span class="o">.</span><span class="n">say_hello</span>   <span class="c1"># =&gt; Hello, Ruby</span>
</span></code></pre></td></tr></table></div></figure>


<p>事實上 Rails 也是大量的使用了這個手法來擴充 Ruby 的功能，像是 <code>2.days.ago</code> 就是個經典的例子(實作方式請見 ActiveSupport 的原始碼)</p>

<p>前面一開始也提到，在 Ruby 裡什麼東西都是物件，包括數字也是，所以其實連最簡單的 1 + 1，其實它是執行了 1 這個物件的 <code>+</code> 方法：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="nb">puts</span> <span class="mi">1</span><span class="o">.</span><span class="n">+</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>所以，透過 open class 的手法，甚至也可以去惡搞一下看起來最簡單的加法：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Fixnum</span>
</span><span class='line'>  <span class="k">alias</span> <span class="ss">:ori_add</span> <span class="ss">:+</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">+</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">ori_add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="o">.</span><span class="n">ori_add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="nb">puts</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">1</span>   <span class="c1"># =&gt; 3</span>
</span></code></pre></td></tr></table></div></figure>


<p>這樣一來就會在數學加法上偷偷的再加 1，像是 1 + 1 = 3, 2 + 2 = 5，以此類推。</p>

<p>不過，Open Class 好用歸好用，風險感覺不小，好像一個不小心就容易被自己或別人改到一些不該改的東西。所以後來 Ruby 有推出了一個叫做 <a href="http://www.ruby-doc.org/core-2.1.3/doc/syntax/refinements_rdoc.html">Refinement</a> 的概念：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">module</span> <span class="nn">StringExtension</span>
</span><span class='line'>  <span class="n">refine</span> <span class="nb">String</span> <span class="k">do</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">to_md5</span>
</span><span class='line'>      <span class="nb">require</span> <span class="s2">&quot;digest/md5&quot;</span>
</span><span class='line'>      <span class="no">Digest</span><span class="o">::</span><span class="no">MD5</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">using</span> <span class="no">StringExtension</span>
</span><span class='line'>
</span><span class='line'><span class="nb">puts</span> <span class="s2">&quot;Ruby&quot;</span><span class="o">.</span><span class="n">to_md5</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Block</h3>

<p>在 Ruby 裡，Block 可以用 do..end 的方式來寫，也可以用大括號來寫，雖然大部份候兩者是可以互相替換的，但有一些微妙的地方沒注意的話，可能會造成預期外的結果，詳情請見<a href="http://blog.eddie.com.tw/2011/06/03/do-end-vs-braces/">Do..End v.s Braces</a>。</p>

<h3>Private method</h3>

<p>在 Ruby 裡只要沒有特別聲明，所有的類別方法都是 public 的。如果想要在 Ruby 裡定義 private method 可以這樣做：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Animal</span>
</span><span class='line'>  <span class="kp">private</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">secret_method</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>或是這樣也可以：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Animal</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">secret_method</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="kp">private</span> <span class="ss">:secret_method</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>看到第二種 private 的寫法，你應該就會發現其實 public、protected 以及 private 在 Ruby 裡並不是關鍵字或保留字，它只是個方法而已。</p>

<p>在 private 方法的定義上，Ruby 跟其它程式語言的定義有些不太一樣。在 Ruby 的 private 方法，是只要沒有明確的指出 recevier 就可以使用，所以即使是子類別也可使用父類別的 private 方法：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Animal</span>
</span><span class='line'>  <span class="kp">private</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">secret_method</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="s2">&quot;Don&#39;t tell anyone!&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Dog</span> <span class="o">&lt;</span> <span class="no">Animal</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">hello</span>
</span><span class='line'>    <span class="n">secret_method</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Dog</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">hello</span>  <span class="c1"># =&gt; Don&#39;t tell anyone!</span>
</span></code></pre></td></tr></table></div></figure>


<p>但其實 Ruby 的 private 方法也不是真的那麼 private：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Animal</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">secret_method</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="kp">private</span> <span class="ss">:secret_method</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">a</span> <span class="o">=</span> <span class="no">Animal</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="n">a</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="ss">:secret_method</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>更多相關細節可參考 <a href="http://blog.eddie.com.tw/2011/07/26/public-protected-and-private-method-in-ruby/">Public, Protected and Private Method in Ruby</a>。</p>

<p>參考資料：<a href="http://en.wikipedia.org/wiki/Message_passing">Message Passing</a></p>

<h3>Dynamic Method</h3>

<p>假設我們有一段程式碼長得像這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">ComputerStore</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_cpu_info</span><span class="p">(</span><span class="n">workstation_id</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_cpu_price</span><span class="p">(</span><span class="n">workstation_id</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_mouse_info</span><span class="p">(</span><span class="n">workstation_id</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_mouse_price</span><span class="p">(</span><span class="n">workstation_id</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_keyboard_info</span><span class="p">(</span><span class="n">workstation_id</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_keyboard_price</span><span class="p">(</span><span class="n">workstation_id</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>有個軟體開發的原則叫做 <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> (Don&#8217;t Repeat Yourself)，簡單的說就是不要一直寫重複的程式。在開發軟體的時候，如果可以把程式碼寫得 DRY 一點，日後在維護的時候也會輕鬆得多。</p>

<p>所以，如果上面這段程式碼假設每個 <code>get_xxx_info</code> 跟 <code>get_xxx_price</code> 的方法實作內容都差不多，以 DRY 原則來看的話，上面這個看起來感覺就相當的「潮」(WET)啊，潮到出水了 XD</p>

<p>在這個時候就可以利用動態定義方法來整理這些看起來很重複的程式碼。在 Ruby 要動態的定義方法，可以用 <code>define_method</code>：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">define_method</span> <span class="ss">:hello</span> <span class="k">do</span> <span class="o">|</span><span class="n">param</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;Hello, </span><span class="si">#{</span><span class="n">param</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">hello</span> <span class="s2">&quot;Ruby&quot;</span>  <span class="c1"># =&gt; Hello, Ruby</span>
</span></code></pre></td></tr></table></div></figure>


<p>所以，原來上面那段看起來不太 DRY 的程式碼，可以整理成這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">ComputerStore</span>
</span><span class='line'>  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">set_component</span><span class="p">(</span><span class="n">component</span><span class="p">)</span>
</span><span class='line'>    <span class="n">define_method</span> <span class="s2">&quot;get_</span><span class="si">#{</span><span class="n">component</span><span class="si">}</span><span class="s2">_info&quot;</span> <span class="k">do</span> <span class="o">|</span><span class="n">workstation_id</span><span class="o">|</span>
</span><span class='line'>      <span class="c1"># ...</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="n">define_method</span> <span class="s2">&quot;get_</span><span class="si">#{</span><span class="n">component</span><span class="si">}</span><span class="s2">_price&quot;</span> <span class="k">do</span> <span class="o">|</span><span class="n">workstation_id</span><span class="o">|</span>
</span><span class='line'>      <span class="c1"># ...</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">set_component</span> <span class="ss">:cpu</span>
</span><span class='line'>  <span class="n">set_component</span> <span class="ss">:mouse</span>
</span><span class='line'>  <span class="n">set_component</span> <span class="ss">:keyboard</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>還可以再簡化一些：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">ComputerStore</span>
</span><span class='line'>  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">set_components</span><span class="p">(</span><span class="o">*</span><span class="n">components</span><span class="p">)</span>
</span><span class='line'>    <span class="n">components</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">component</span><span class="o">|</span>
</span><span class='line'>      <span class="n">define_method</span> <span class="s2">&quot;get_</span><span class="si">#{</span><span class="n">component</span><span class="si">}</span><span class="s2">_info&quot;</span> <span class="k">do</span> <span class="o">|</span><span class="n">workstation_id</span><span class="o">|</span>
</span><span class='line'>        <span class="c1"># ...</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="n">define_method</span> <span class="s2">&quot;get_</span><span class="si">#{</span><span class="n">component</span><span class="si">}</span><span class="s2">_price&quot;</span> <span class="k">do</span> <span class="o">|</span><span class="n">workstation_id</span><span class="o">|</span>
</span><span class='line'>        <span class="c1"># ...</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">set_components</span> <span class="ss">:cpu</span><span class="p">,</span> <span class="ss">:mouse</span><span class="p">,</span> <span class="ss">:keyboard</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>這樣一來，以後如果要再加硬體，也只要在 <code>set_components</code> 後面加上去就行了，看起來應該比原來的好維護多了。</p>

<h3>Method Missing</h3>

<p>如果大家曾經使用過 Rails，也許多少有用過類似 <code>Book.find_by_id</code> 或 <code>Book.find_by_name</code> 的神奇語法。你可能很好奇，為什麼明明你沒有定義這些方法，也一樣可以正常執行不會出錯?</p>

<p>其實，Ruby 在尋找方法的時候，會先往該物件的所屬類別找，找不到會再往它的父類別找(其實真正尋找方法的細節更複雜一些 XD)，如果一直找不到，最後就會呼叫 <code>method_missing</code> 這個方法。</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">method_name</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
</span><span class='line'>  <span class="nb">puts</span> <span class="s2">&quot;You just called a method </span><span class="si">#{</span><span class="n">method_name</span><span class="si">}</span><span class="s2"> with </span><span class="si">#{</span><span class="n">args</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">some_method_not_exist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
</span><span class='line'><span class="c1"># =&gt; You just called a method some_method_not_exist with [1, 2, 3]</span>
</span></code></pre></td></tr></table></div></figure>


<p>所以當你在適當的地方覆寫了 <code>method_missing</code>，就可以做出類似的效果：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Book</span>
</span><span class='line'>  <span class="k">class</span> <span class="o">&lt;&lt;</span> <span class="nb">self</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">method_name</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
</span><span class='line'>      <span class="k">if</span> <span class="n">method_name</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">start_with?</span><span class="p">(</span><span class="s2">&quot;find_by&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="n">q</span> <span class="o">=</span> <span class="n">method_name</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">&quot;find_by_&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="nb">puts</span> <span class="s2">&quot;find something by </span><span class="si">#{</span><span class="n">q</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'>      <span class="k">else</span>
</span><span class='line'>        <span class="k">super</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Book</span><span class="o">.</span><span class="n">find_by_id</span>    <span class="c1"># =&gt; find something by id</span>
</span><span class='line'><span class="no">Book</span><span class="o">.</span><span class="n">find_by_name</span>  <span class="c1"># =&gt; find something by name</span>
</span><span class='line'><span class="no">Book</span><span class="o">.</span><span class="n">wtf</span>           <span class="c1"># =&gt; ERROR!</span>
</span></code></pre></td></tr></table></div></figure>


<p>看到了嗎? 即使原先沒有定義 <code>Book.find_by_id</code> 或 <code>Book.find_by_name</code>，在執行時候因為 <code>find_by</code> 開頭的方法被我自己寫的 <code>method_missing</code> 給攔了下來而不會出錯，但其它以外的方法則會呼叫內建的 <code>method_missing</code> 而噴出錯誤訊息。</p>

<h2>有趣(或奇怪)的 Ruby 語法</h2>

<p>寫程式有時候是件很悶的工作，偶爾寫點有趣的程式碼娛樂別人或自己也不錯。像是下面這個在 <a href="https://github.com/tric/trick2013">Trick 2013</a>比賽中是「Most readable」的程式碼：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">begin</span> <span class="n">with</span> <span class="n">an</span> <span class="n">easy</span> <span class="n">program</span><span class="o">.</span>
</span><span class='line'><span class="n">you</span> <span class="n">should</span> <span class="n">be</span> <span class="n">able</span> <span class="n">to</span> <span class="n">write</span>
</span><span class='line'><span class="n">a</span> <span class="n">program</span> <span class="k">unless</span> <span class="k">for</span> <span class="n">you</span><span class="p">,</span>
</span><span class='line'><span class="n">program</span> <span class="k">in</span> <span class="n">ruby</span> <span class="n">language</span> <span class="n">is</span>
</span><span class='line'><span class="n">too</span> <span class="n">difficult</span><span class="o">.</span> <span class="no">At</span> <span class="n">the</span> <span class="k">end</span>
</span><span class='line'><span class="n">of</span> <span class="n">your</span> <span class="n">journey</span> <span class="n">towards</span> <span class="n">the</span>
</span><span class='line'><span class="n">ultimate</span> <span class="n">program</span><span class="p">;</span> <span class="n">you</span> <span class="n">must</span>
</span><span class='line'><span class="n">be</span> <span class="n">a</span> <span class="n">part</span> <span class="n">of</span> <span class="n">a</span> <span class="n">programming</span>
</span><span class='line'><span class="n">language</span><span class="o">.</span> <span class="no">You</span> <span class="n">will</span> <span class="k">end</span> <span class="k">if</span>
</span><span class='line'><span class="n">you</span> <span class="o">!=</span> <span class="n">program</span>
</span></code></pre></td></tr></table></div></figure>


<p>寫得感覺像是一篇文章(其實內文無意義)，但其它是一段可以正常執行不會發生錯誤的 Ruby 程式碼。下面這個則是「Best way to return true」：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="vg">$ruby</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Object</span><span class="p">){</span><span class="o">|</span><span class="n">oriented</span><span class="o">|</span> <span class="n">language</span><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>因為在 Ruby 的 global variable 預設值是 nil，又，在 Ruby 什麼東西都是物件，包括 nil 也是，所以 <code>$ruby.is_a?(Object)</code> 會回傳 true。至於後面傳入的 Block 因為不會被呼叫，所以傳什麼進去都無所謂了。</p>

<p>阿宅寫程式也可以很浪漫的：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="no">It</span> <span class="n">can</span> <span class="n">be</span> <span class="n">wonderful</span> <span class="k">if</span> <span class="s2">&quot;the world&quot;</span><span class="o">.</span><span class="n">end_with?</span> <span class="s2">&quot;you&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>或是：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">I</span> <span class="n">will</span> <span class="n">love</span> <span class="n">you</span> <span class="k">until</span> <span class="s2">&quot;the end of the world&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>這其實只是透過邏輯短路(Short-circuit)玩的把戲，因為後面的 if 或 until 在經過評估之後都不會成立，所以前面的語法就算有錯也不會被執行到。</p>

<p>另外，其實 Ruby 的類別名稱也就只是個常數而已，所以這樣惡搞你的同事也是 ok 的&#8230;</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">BookList</span> <span class="o">&lt;</span> <span class="p">(</span><span class="nb">rand</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span> <span class="p">?</span> <span class="nb">Array</span> <span class="p">:</span> <span class="no">Hash</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">b</span> <span class="o">=</span> <span class="no">BookList</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="n">b</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;Ruby&quot;</span>   <span class="c1"># =&gt; 將有 10% 的機會發生錯誤</span>
</span></code></pre></td></tr></table></div></figure>


<p>因為 Ruby 的方法名字不一定只能用英文字母，所以可以寫出像這樣的程式碼：
<img src="http://blog.eddie.com.tw/images/2014/ruby_code_fish.png" alt="image" /><br />
看著看著就覺得餓了&#8230;</p>

<p>然後如果你知道 <code>attr_accessor</code> 其實也只是個會幫你產生一對 getter/setter 的類別方法的話，對產生的 getter/setter 不滿意或是想要再做些別的事話，也可以自己定義：
<img src="http://blog.eddie.com.tw/images/2014/ruby_code_girl.png" alt="image" /><br />
這樣你就寫出了一個「可以永保青春的&#8221;方法&#8221;」了 XD</p>

<h3>小結</h3>

<p>看到這裡，你可能會覺得在 Ruby 變數不用宣告就可直接用，內建類別可以透過 Open Class 方式來惡搞，private 方法又一點都不 private，整個只像是僅供參考，這樣不會很恐怖嗎?</p>

<p>我想，開發者大多知道自己在做什麼。當初 Ruby 在設計的時候是採取相信開發者的立場，給開發者很大的彈性與自由，這其實也是我最後選擇 Ruby 的原因。</p>

<p>Ruby/Rails 被很多人認為是很魔術的程式語言或工具，但只要瞭解它是怎麼運作的，其實也沒真的非常神奇。技術不用學多，一、二門專精的練起來就已可不愁吃穿了。</p>

<p>最後，
引用一段最近在朋友的 Facebook 上看到的一段話：</p>

<blockquote><p>&#8220;Difference between a master and a beginner? The master has failed more times than the beginner has even tried.&#8221;<br/>&#8220;大師與新手之間的差別，就是大師失敗過的次數，比新手嘗試過的次數還多&#8221;</p></blockquote>


<p>共勉之 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[「有心人」之 Ruby 課程]]></title>
    <link href="http://blog.eddie.com.tw/2014/08/22/lets-learn-ruby/"/>
    <updated>2014-08-22T07:35:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/08/22/lets-learn-ruby</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2014/ruby_word.jpg" alt="image" /></p>

<p>記得在去年年初的時候，因為自己想找幾個一起打拼的伙伴而發起了一個「<a href="http://blog.eddie.com.tw/2013/04/22/1st-ruby-and-rails-training-course/">有心人</a>」的活動，感謝大家的捧場以及社群朋友們的支持，活動順利結束。</p>

<p>然後，一直掛在嘴邊說要辦的「第二梯次」，總因為手邊的雜務而擱置。雖然後來斷斷續續的也有在中研院的自由軟體工作坊開一些 Ruby 的入門課或是在社群活動的分享，但就似乎變成有空才能開。</p>

<p>現在，我們成立了一家叫做<a href="http://5xruby.tw">五倍紅寶石</a>的公司，在更多朋友的幫忙下，我們有更多的時間及資源可以來做推廣 Ruby 這件事了，畢竟推廣 Ruby 本來也是當初成立這家公司的最主要目的。</p>

<p>所以，在與夥伴們討論後，我們決定要來持續的無料推廣 Ruby，每個月固定至少會有個一天是 Ruby 推廣課程，希望可以讓更多人可以認識這個有趣可愛的程式語言。</p>

<p>詳情請見：<a href="http://5xruby.tw/courses/lets-learn-ruby-1">http://5xruby.tw/courses/lets-learn-ruby-1</a></p>

<ul>
<li>上課地點：台北車站附近</li>
<li>費用：0 元，惟上課學員需自備筆電，作業系統不限。</li>
</ul>


<p>歡迎大家都可以開開心心的來認識、學習這個有趣的程式語言 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Code Swift with Vim]]></title>
    <link href="http://blog.eddie.com.tw/2014/08/07/code-swift-with-vim/"/>
    <updated>2014-08-07T07:35:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/08/07/code-swift-with-vim</id>
    <content type="html"><![CDATA[<p>Swift 是今年 Apple 發表的程式語言，在發表的隔月就衝上了 <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">TIOBE 排行榜</a>的前 20 名。不過因為目前還在 Beta 中，所以除了改規格之外，開發工具的穩定性也還有待加強。</p>

<p>因為我已習慣用終端機 + Vim 工作，所以用 Vim 來練習寫 Swift 也是很正常的(誤)。不過其實真正的原因是之前 beta 版的 Xcode 太容易因為語法錯誤而當掉了。</p>

<h2>Vim plugin</h2>

<p>Vim 什麼沒有，plugin 最多了。不過因為 Swift 剛出來沒多久，外掛還不太多。我目前只有使用 <a href="https://github.com/toyamarinyon/vim-swift">vim-swift</a> 這個 plugin，有支援語法 highlight。</p>

<h2>Swift REPL</h2>

<p>寫 Ruby/Rails 時已很習慣有 <code>irb</code> 之類的 REPL(Read–Eval–Print Loop) 可以用，Swift 這回也有提供 REPL。</p>

<p>因為在我電腦裡同時有安裝 Xcode 5 以及 Xcode 6 beta 5，所以在使用前得需先修改一下設定，開啟終端機後輸入：</p>

<pre><code>$ sudo xcode-select -switch /Applications/Xcode6-Beta5.app
</code></pre>

<p>上面這個指令路徑設定可能會隨著 Xcode 6 的版本不同而需要做些調整。設定完之後，輸入：</p>

<pre><code>$ xcrun swift
</code></pre>

<p>或</p>

<pre><code>$ lldb --repl
</code></pre>

<p>即可進入 Swift 的 REPL 環境。</p>

<p><img src="http://blog.eddie.com.tw/images/2014/swift_repl.png" width="600" alt="image" /></p>

<h2>編譯</h2>

<p>如果只是要寫個沒有畫面的小工具的程式，其實是不需要開 Xcode 的，只要一個簡單的 .swift 檔就可以了。</p>

<pre><code>// 檔案 hello.swift
println("Hello, Swift!")
</code></pre>

<p>然後執行：</p>

<pre><code>$ xcrun swift hello.swift
</code></pre>

<p>應該會在畫面上印出 <code>Hello, Swift!</code> 字樣。如果想要進行編譯，可執行：</p>

<pre><code>$ xcrun swiftc hello.swift
</code></pre>

<p>這會在該目錄產生一個同名的 <code>hello</code> 執行檔(注意，是 <code>swiftc</code> 而不是 <code>swift</code>)。</p>

<iframe width="420" height="315" src="http://www.youtube.com/embed/h6n4RlHk12I" frameborder="0" allowfullscreen></iframe>


<p>註：以上是以 Xcode 6 Beta 5 為示範，在之前的版本的指令稍有不同。</p>

<h2>自動執行</h2>

<p>如果每次寫完存檔就要再執行一次 <code>xcrun swift</code> 也太辛苦了，工程師都是很懶的。有個不錯用的 gem 叫做 <a href="https://github.com/guard/guard">Guard</a>可以幫你監視檔案的狀態，一但檔案有異動就跟著執行某些指令。</p>

<p>安裝 gem 是件輕鬆愉快的事，只要一行：</p>

<pre><code>$ gem install guard-shell
</code></pre>

<p>如果安裝順利，下一步是請 guard 幫我們產生一個 Guardfile：</p>

<pre><code>$ guard init shell
</code></pre>

<p>你應該可以在該目錄看到 Guardfile 檔案。我稍微做了些小修改如下：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="n">guard</span> <span class="ss">:shell</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">watch</span><span class="p">(</span><span class="sr">/(.*).swift/</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">m</span><span class="o">|</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="s2">&quot;-&quot;</span> <span class="o">*</span> <span class="mi">20</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="sb">`xcrun swift </span><span class="si">#{</span><span class="n">m</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="si">}</span><span class="sb">`</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>這個設定檔沒有很特別的東西，大概就是每次執行前先印出個分隔線，然後再印出 <code>xcrun swift</code> 的執行結果。接著只要在該目錄執行 <code>guard</code> 即可進入監看模式。</p>

<iframe width="420" height="315" src="http://www.youtube.com/embed/yhPu86RvilI" frameborder="0" allowfullscreen></iframe>


<h2>小結</h2>

<p>因為 Vim 指法已習慣成肌肉記憶(muscle memory)，所以我的 Xcode 也通常會安裝 <a href="https://github.com/JugglerShu/XVim">XVim</a> 讓 Xcode 可支援部份的 Vim 指令，不然完全沒辦法工作了。</p>

<p>是說像這樣用 Vim 寫 Swift，練練語法還 ok，但要靠 Vim 純手工刻出 iOS app 真的不是一般人能做到的事，所以其實我真正開發的時候，還是需要依賴 IDE 幫忙的，不然 method name 那麼長、參數那麼多，不靠 IDE 的自動完成，怎麼可能記得住。</p>

<p>即使如此，我個人還是覺得，可以用 Vim 寫程式，就是莫名的有種阿宅的浪漫啊 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[五倍祝福，五倍的紅寶石]]></title>
    <link href="http://blog.eddie.com.tw/2014/05/29/5xruby/"/>
    <updated>2014-05-29T03:00:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/05/29/5xruby</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2014/5xruby.jpg" alt="image" /></p>

<p>這回，您不需要自己斷開鎖鏈或斷開魂結，也不用燒毀什麼東西了 :)</p>

<p>「五倍紅寶石」是我與幾位台灣 Ruby 社群的朋友共同成立的一家公司，希望可以透過藉由教育訓練、企業培訓等課程，將 Ruby 推廣給更多的企業、開發者。</p>

<p>網站：<a href="http://5xruby.tw" target="_blank">http://5xruby.tw</a></p>

<h3>緣起</h3>

<p>我們是一群在台灣的 Ruby 程式語言的愛好者，每天的工作都是跟 Ruby / Rails 相關。</p>

<p>近一、二年來，Ruby / Rails 的人才需求增加，年薪超過百萬的高薪職缺紛紛出現，吸引越來越多人想要進入 Ruby / Rails 的領域。除自行學習以外，也很積極參加社群舉辦的聚會與分享、交流。</p>

<p>我們這幾年來持續的在台灣大專院校（成大、輔大、台北商專..等校) 開授 Ruby 以及 Rails 課程，觀察學生們的學習狀況，大多覺得 Ruby / Rails 其實並不難學，自己看書或是照著官網文件練習就能練到一定的程度。但要進階至可滿足實戰需求，不容易藉由自學可以短期達成，而是需要更多的實戰經驗，或是導師的帶領。也因此，在台灣，較資深或有經驗的 Ruby / Rails 開發者相當難找。</p>

<p>我們也走訪了一些企業的 IT 部門，請教他們為什麼不採用 Ruby / Rails 的原因，大多也是因為資深的 Ruby / Rails 的工程師難找，或是背後沒有商業公司的技術支援，遇到問題的時候不知道該找誰求救。</p>

<p>於是，我們這幾位愛好 Ruby 的朋友便開始討論「也許我們應該來成立一間專門提供 Ruby/Rails 相關的技術諮詢或是教育訓練的公司」。</p>

<p>我們最終的目的，是希望在台灣可以有越來越多的企業能了解或採用 Ruby 這個優雅、有趣，並且極具生產力的程式語言做為主要開發工具，更快速的實現您的想法。</p>

<p>感謝多位業界前輩、先進的支持與鼓勵：</p>

<blockquote><p>Programmer 最有價值的是經驗值，「五倍紅寶石」的導師都是社群內數一數二的資深 Rubyist，由他們來帶領學員一探 Ruby 世界的神奇之處，實在是最佳選擇。</p><footer><strong>Victor Lam</strong><cite>EZTABLE 香港總經理</cite></footer></blockquote>




<blockquote><p>Eddie and his team are of the most dedicated Ruby evangelists I have ever come across. With their passion and professionalism, Ruby learners will leapfrog in their progress.</p><footer><strong>Jason Hsu</strong><cite>Founder of the Big Questions & TEDxTaipei</cite></footer></blockquote>




<blockquote><p>還在尋找專業的 Ruby/Rails 師資嗎？別懷疑了，台灣最頂尖的 Rubyist 盡在「五倍紅寶石」！</p><footer><strong>Felix Lin</strong><cite>「搭配」網站創辦人</cite></footer></blockquote>




<blockquote><p>慕凡和龍哥是業界數一數二的 Ruby 大師，他們不光是底子深厚，也很懂得引導、訓練學習路上遇到挫折的 Ruby/Rails 學子。很慶幸有他們的協助讓我進入紅寶石的美妙世界。</p><footer><strong>花水木 Hana Chang</strong><cite>Co-Founder and CEO of BountyHunter</cite></footer></blockquote>




<blockquote><p>選擇程式語言很重要，但選擇優秀的導師更重要！能跟擁有多年 Ruby/Rails 實戰經驗、活躍於社群的頂尖 Rubyist 學習，將一窺程式開發殿堂之藝術！我堅信：專業事讓專業的來，而專業的「五倍紅寶石」是寶藏，就等大家來挖掘。</p><footer><strong>謝耀輝 John Sie</strong><cite>Accuvally Inc.共同創辦人暨營運長</cite></footer></blockquote>




<blockquote><p>「五倍紅寶石」的導師們都是業界經驗豐富的實戰高手，提供的課程及咨詢絕對能讓你大幅省去自行摸索的時間。</p><footer><strong>Ben Lin</strong><cite>CEO@POP</cite></footer></blockquote>




<blockquote><p>曾有幸與徐曦與見龍一起工作，徐曦自我要求與向上進取的態度令人稱佩，見龍對危機處理與當責的責任感也值得稱許。「五倍紅寶石」的其他夥伴也是一時之選，相信這是一個很棒的組合。</p><footer><strong>呂元鐘 Max Lu</strong><cite>Buyble 國際精品購物 創辦人</cite></footer></blockquote>


<h3>公司名字的由來</h3>

<p>為什麼公司會取這個看起來有點好笑的名字? 話說某天下午，我們幾個人在討論公司要取什麼名字&#8230;</p>

<p>「紅寶石股份有限公司? 聽起來好普通，而且會不會大家以為我們是珠寶商啊」。</p>

<p>就在大家一直想不到個有代表性又好記的名字的時候，突然來了一個「五倍紅寶石」，大家都笑了，但就在一陣狂笑之中，大家一致鼓掌通過決定要用這個聽起來有點 kuso 的名字了 XD</p>

<h3>怎麼決定負責人是誰的?</h3>

<p>即然是一家 Ruby 公司，Ruby 公司的事當然就是要交給 Ruby 解決。所以我們打開了 <code>irb</code>，輸入一段簡單的程式碼：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="o">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="o">].</span><span class="n">sample</span>
</span></code></pre></td></tr></table></div></figure>


<p>嗯，我們的負責人這樣選出來了 XD</p>

<h3>說明會</h3>

<p>如果您對我們的課程有興趣，或是不知道「五倍紅寶石」到底是在賣什麼藥，歡迎您 6/5（星期四）晚上 19:30 前來參加我們舉辦的說明會，我們在現場將準備一些簡單的點心及飲料。</p>

<p>當然，只是要來閒聊或是找好陣子不見的朋友聚一聚也很歡迎。</p>

<ul>
<li>時間：2014/6/5 星期四 19:30</li>
<li>地點：TED x Taipei Space</li>
<li>地址：台北市金山南路一段 9 號 4 樓</li>
</ul>


<p>請按<a href="http://www.accupass.com/go/5xruby" target="_blank">這裡</a>前往報名網站</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rails Girls in Taipei]]></title>
    <link href="http://blog.eddie.com.tw/2014/04/30/rails-girls-in-taipei/"/>
    <updated>2014-04-30T21:00:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/04/30/rails-girls-in-taipei</id>
    <content type="html"><![CDATA[<p><a href="http://www.slideshare.net/aquarianboy/rails-girls-in-taipei" target="_blank"><img src="http://blog.eddie.com.tw/images/2014/rails_girls_logo.png" alt="image" /></a></p>

<p>This is my lightning talk slide on RubyConf Taiwan 2014:<br />
<a href="http://www.slideshare.net/aquarianboy/rails-girls-in-taipei">http://www.slideshare.net/aquarianboy/rails-girls-in-taipei</a></p>

<p>Hi, I’m Eddie, one of the organizers of <a href="http://railsgirls.com/taipei">Rails Girls Taipei</a>. Last year, I went to <a href="http://rubykaigi.org/2013">RubyKaigi</a> in Japan, and visited the Rails Girls event in Ruby Hiroba(広場). I found that the attendees were divided into “beginner” level and the other level which might be a little familiar with programming, and every coach take care 2 or 3 attendees, so they can coaching them one by one.</p>

<p>We thought it might be interesting if we can also have this event in Taiwan. So, <a href="https://twitter.com/taiansu">Taian</a>, <a href="https://twitter.com/ryudoawaru">Ryudo</a>, and <a href="https://twitter.com/eddiekao">me</a>, we three decided to host a Rails Girls event in Taiwan, just give it a try.</p>

<p>Our first event is on last September. We recruited about 10 to 15 coaches and discuss the detail, but we totally have no experience about this event.</p>

<p>We thought there won’t be any girl willing to join this kind of nerdy event. But surprisingly, there’re more than 300 girls signed up just in one day.</p>

<p>We eventually didn’t pick neither CS students or web developers, instead, we prefer those who are totally new to programming, we wanna see what will happen if we try to bring Ruby and Rails to them.</p>

<p>Looks like they all have a good time :)</p>

<p><img src="http://blog.eddie.com.tw/images/2014/rails_girls_taipei_4.jpg" alt="image" />
<img src="http://blog.eddie.com.tw/images/2014/rails_girls_taipei_2.jpg" alt="image" /></p>

<p>And our second event is on last November. Still, more than 300 girls signed up again, and this time we recruited about 25 coaches and 75 attendees. You might have also noticed that, several coaches are also the speakers in conference this year.</p>

<p><img src="http://blog.eddie.com.tw/images/2014/rails_girls_taipei_1.jpg" alt="image" />
<img src="http://blog.eddie.com.tw/images/2014/rails_girls_taipei_3.jpg" alt="image" /></p>

<p>you can visit <a href="https://www.facebook.com/railsgirlstw/photos_albums">here</a> to see more photos. It’s awesome for me to see them open a terminal window and run some commands on they computer, it’s really cool.</p>

<p>Last month, we had the third event. Until now, we have more than 150 rails girls already.</p>

<p>Durning RubyConf Taiwan 2014, there are about 20 female volunteers in check-in counter or at the booths are from Rails Girls, they did help a lot in this conference.</p>

<p>Of course, you know, it’s not quite possible to learn Ruby on Rails just in a 2-day workshop, so some girls asked:”is there any other course to learn more?” Well, then we decided to have a weekly event for them, named “<a href="http://ltrt.kktix.cc/">Let’s Try Rails Tuesday</a>”, a.k.a “LTRT”.  Which is mainly hosted by <a href="https://twitter.com/ManicLF">manic</a>, also the speaker in this conference.</p>

<p>Currently, we’ve already had 16 LTRT events, and about 20 attendees per week, even in the rainy days.</p>

<p><img src="http://blog.eddie.com.tw/images/2014/rails_girls_taipei_5.jpg" alt="image" /></p>

<p>Beside that, we also tried to do some promotions in high school or university, hope more people can understand what we were doing :)</p>

<p>Anyway, I have to thank all our coaches, it won’t work without your help.</p>

<p>We will have more Rails Girls event in the future if possible, so we&#8217;ll need more coaches, please let me know if you’re interested in being a coach.</p>

<p>Of course, we need more sponsorship :)</p>

<p>At last, this is our <a href="https://www.facebook.com/railsgirlstw">fan page</a> on Facebook, feel free to join us for more information. Please don&#8217;t be hesitate to contact me if you have any question, any comment will be appreciated.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Taipei.rb 起步走]]></title>
    <link href="http://blog.eddie.com.tw/2014/03/03/taipei-ruby-group/"/>
    <updated>2014-03-03T04:50:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2014/03/03/taipei-ruby-group</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2014/ruby_word.jpg" alt="image" /></p>

<p>台北的 Ruby 社群跟相關活動其實不算少，除了一些個人或學校社團的活動外，人數較多的活動有例如每一、二個月舉辦一次的 Ruby Tuesday，會邀請特定的來賓來分享他們在工作上或個人研究上的專業主題；有年度大型活動 <a href="http://rubyconf.tw/">RubyConf Taiwan</a>，會邀請國內外對 Ruby/Rails 有研究的高手來分享他們的心得，甚至連 Ruby 的老爸 Matz 也會來。除此之外，還有女性朋友專屬的 <a href="http://railsgirls.tw/">Rails Girls</a> 以及每週進行的 <a href="http://ltrt.kktix.cc/">Rails Girls 活動</a> (每週約二十人左右參加)。</p>

<h2>又一個 Ruby 聚會?</h2>

<p>不過，上述這些活動不是主題不適合新手，或是主題不容易引起共鳴，不然就是有性別限制，像我這種好像會寫一點點程式的高級新手想要找到同好一起學習反而變得不太容易。</p>

<h2>目的/方向</h2>

<p>所以，為了能讓更多對 Ruby/Rails 有興趣的朋友可以有個可以固定而且定期的交流管道，幾位 Ruby 圈的朋友(<a href="https://www.facebook.com/eddiekao">我</a>、<a href="https://www.facebook.com/ryudoawaru">慕凡</a>、<a href="https://www.facebook.com/manic.chuang">Manic</a> 以及 <a href="https://www.facebook.com/tonytonyjan">大兜</a>)就打算來籌備這樣的一個活動。我們想了好幾個名字，最後大家鼓掌通過的名字是「Taipei.rb」</p>

<p>活動的方向很簡單，就是「讀書」 + 「閒聊」。</p>

<p>不像 Ruby Tuesday 之類的主題式分享，Taipei.rb 初期設定的方向是「讀書會」，會先挑幾本書來跟大家一起讀、一起討論，每次活動開始會有一到二位與會者上台進行導讀，並從參與者中挑選下回活動上台的人。</p>

<p>新手/老鳥不拘，願意讀書就行，來找人閒聊或是來求職、求才也都歡迎。當然，性別不拘 :)</p>

<h2>目前暫定書目：</h2>

<h3>Ruby 相關</h3>

<ul>
<li><a href="http://eloquentruby.com/">Eloquent Ruby</a></li>
<li><a href="http://www.amazon.com/Metaprogramming-Ruby-Program-Like-Pros/dp/1934356476">Metaprogramming Ruby</a></li>
</ul>


<h3>Rails 相關：</h3>

<ul>
<li><a href="https://leanpub.com/tr4w">Rails 4 Way</a></li>
<li><a href="http://ruby.railstutorial.org/">Rails Tutorial</a></li>
</ul>


<h2>週期</h2>

<p>預計每二星期舉辦一次。</p>

<h2>費用</h2>

<p>每人僅需負擔場地費用(約 NT 200 元)即可，不另外收取費用。</p>

<h2>第 0 次兼說明會</h2>

<p>如果各位看完還是不知道這個活動要幹嘛，我們在星期二(3/4)晚上七點，在 DeRoot 有個說明會兼第 0 次的導讀示範，有興趣的朋友請按<a href="http://taipeirb.kktix.cc/events/0000">這裡</a>報名。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[再見 2013，哈囉 2014!]]></title>
    <link href="http://blog.eddie.com.tw/2013/12/31/hello-2014/"/>
    <updated>2013-12-31T02:52:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2013/12/31/hello-2014</id>
    <content type="html"><![CDATA[<p>很快的，2013 年結束了，照例看了一下 2013 年的<a href="http://blog.eddie.com.tw/2013/01/01/hello-2013/">許願清單</a>，完成度差不多只有六成，還有很多進步的空間。</p>

<h2>2013 年幹了哪些事</h2>

<ul>
<li>今年有 <a href="http://blog.eddie.com.tw/presentations">22 場公開的活動</a>，雖然有點累，但很有趣!</li>
<li>第一屆的 <a href="http://webconf.tw/">WebConf Taiwan</a> 真的非常感謝大家的支持、捧場，活動算是圓滿結束。</li>
<li>今年第一次厚臉皮的辦了 <a href="http://blog.eddie.com.tw/2013/04/22/1st-ruby-and-rails-training-course/">Ruby/Rails 有心人</a>活動，感謝大家的支持。</li>
<li>今年在日本舉辦的 <a href="http://rubykaigi.org/2013">RubyKaigi</a> 剛好有榮幸投稿上了，所以同時解除了第一次在國外發表演說以及第一次用全英文演講 25 分鐘的成就，也在日本見識到了什麼才叫認真的技術魔人。</li>
<li>在台北舉辦了兩次的 <a href="http://railsgirls.com/taipei">Rails Girls</a> 活動，出乎意外的受歡迎。</li>
<li>十月份帶了一家四口前往日本遊山玩水一個多星期，勉強算是有個交待了。</li>
</ul>


<h2>希望可以更熟悉的技能</h2>

<p>資訊這一行，要學習的東西、想要做的事情太多，但人生有限，所以 2014 年只會把時間集中放在這些地方了：</p>

<ul>
<li>iOS app / Cocoa Framework：這是目前幾乎 80% 的工作時間都在這上面了，不再精進一些怎麼行。</li>
<li>Ruby / Rails：很有趣的而且具生產力的程式語言/網頁框架，但常看到其它高手的寫法就會覺得自己還差得遠。</li>
<li>Golang：身邊的朋友不少都投入這個新語言，在效能上有很優異的表現，是時候該學習它了 :)</li>
</ul>


<h2>許願</h2>

<ul>
<li>希望小朋友們可以平安長大，2014 年也可以再帶他們一起來去旅行。</li>
<li>希望 WebConf Taiwan 2014 可以順利進行。</li>
<li>希望 Rails Girls 活動可以繼續辦下去。</li>
<li>希望「有心人」課程可以繼續辦下去。</li>
<li>希望繼續推廣 Ruby 給更多的朋友知道。</li>
<li>希望手上正在做的產品可以順利完成。</li>
<li>希望公司生意&#8230; 順利就好。</li>
</ul>


<p>許了一堆願望，2014 年也要繼續努力!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[id 與 instancetype]]></title>
    <link href="http://blog.eddie.com.tw/2013/12/16/id-and-instancetype/"/>
    <updated>2013-12-16T07:35:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2013/12/16/id-and-instancetype</id>
    <content type="html"><![CDATA[<p>這星期我們再來看個有點冷門但我覺得還滿有趣的小東西：<strong>instancetype</strong>。如果我們去翻一下 <code>NSObject</code> 上 <code>alloc</code> 跟 <code>init</code> 的定義：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">// 檔案：NSObject.h</span>
</span><span class='line'><span class="k">@interface</span> <span class="nc">NSObject</span> <span class="o">&lt;</span><span class="n">NSObject</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">Class</span> <span class="n">isa</span>  <span class="n">OBJC_ISA_AVAILABILITY</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="n">init</span><span class="p">;</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nf">new</span><span class="p">;</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nf">alloc</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>會發現 <code>alloc</code> 跟 <code>init</code> 的回傳型態都是 <code>id</code>。而在<a href="http://blog.eddie.com.tw/2013/12/05/object-class-and-meta-class-in-objective-c/">上一篇</a>提到，在 Objective-C 裡 <code>id</code> 是一個可以指向任何物件的指針，所以如果這樣寫的話：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="n">NSArray</span><span class="o">*</span> <span class="n">myArray</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSArray</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>看起好像沒什麼問題，執行起來也正常，但這裡就有個小小的疑惑了.. 即然 <code>alloc</code> 跟 <code>init</code> 都是回傳 <code>id</code> 型別，Objective-C 是個動態語言，很多資訊是在執行階段(runtime)才會取得，那編譯器(compiler)又是怎麼知道它應該要是個 <code>NSArray</code>?</p>

<!-- more -->


<p>根據 <a href="http://clang.llvm.org/docs/LanguageExtensions.html">Clang 的文件</a>說明，原來當我們寫 <code>[NSArray alloc]</code> 的時候，訊息接受者(receiver，也就是 <code>NSArray</code>)收到訊息(message，也就是 <code>alloc</code>)，它並不是真的就乖乖的就只傳回 <code>id</code> 型別，而是回傳 receiver 的型別(a.k.a related result type)，在這個例子就是 <code>NSArray</code>。同理 <code>init</code> 也是一樣，所以 <code>[[NSArray alloc] init]</code> 也會偷偷的回傳 <code>NSArray</code> 型別。在 Objective-C 裡，<code>alloc</code>、<code>new</code>、<code>init</code> 等方法都享有這個特別的服務。</p>

<p>但如果不是這些享有特別服務的方法呢? 例如：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">@interface</span> <span class="nc">Animal</span> : <span class="nc">NSObject</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span> <span class="nf">createAnimal</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">Animal</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span> <span class="nf">createAnimal</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">[[</span><span class="n">self</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@interface</span> <span class="nc">Fox</span> : <span class="nc">Animal</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">say</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">Fox</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">say</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;what does the fox say!?&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>這裡我們建立了兩個類別，一個 <code>Animal</code> 一個 <code>Fox</code>，<code>Fox</code> 繼承自 <code>Animal</code>，並且在 <code>Animal</code> 定義了一個類別方法 <code>createAnimal</code>。看起來很正常，但如果接下來不小心這樣寫的話：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="p">[[</span><span class="n">Animal</span> <span class="n">createAnimal</span><span class="p">]</span> <span class="n">say</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>上面這行在編譯階段沒問題，但執行之後就會 crash 了。我們一般不會這樣寫，因為我們光用肉眼就能發現問題在哪裡，父類別 <code>Animal</code> 根本沒有定義或實作 <code>say</code> 方法所以理所當然的會 crash。但為什麼這麼明顯的錯誤在 Xcode 裡沒被挑出來? 因為 <code>+createAnimal</code> 這個方法回傳的是 <code>id</code>，編譯器沒辦法在編譯階段從 <code>id</code> 推敲出它真正的型別，所以只好先放它過關，然後在執行階段就 crash 了。(關於為什麼是在執行階段才知道型別，可參考<a href="http://blog.eddie.com.tw/2013/12/05/object-class-and-meta-class-in-objective-c/">這一篇</a>的介紹)</p>

<p>你當然也可以在執行階段再用 <code>respondsToSelector:</code> 之類的方法來檢查，但事實上這個工作可以交給編譯器來做，只要把 <code>id</code> 換成 <code>instancetype</code>，像這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">@interface</span> <span class="nc">Animal</span> : <span class="nc">NSObject</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span> <span class="nf">createAnimal</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">Animal</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span> <span class="nf">createAnimal</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">[[</span><span class="n">self</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>這樣編譯器就會在原本會 crash 的那行跳出一個紅色的警告：</p>

<p><img src="http://blog.eddie.com.tw/images/2013/instancetype_error_check.png" alt="image" /></p>

<p>寫著：</p>

<pre><code>No visible @interface for 'Animal' declares the selector 'say'
</code></pre>

<p>在編譯過程就會幫你把這個問題抓出來了。使用 <code>instancetype</code> 的另一個好處，就是在子類別也可以正確的知道子類別的型別，例如你不小心這樣寫：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="p">[[</span><span class="n">Fox</span> <span class="n">createAnimal</span><span class="p">]</span> <span class="nl">addObject:</span><span class="s">@&quot;hello, fox!&quot;</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>如果這邊回傳的是 <code>id</code> 的話，上面這行在編譯階段也不會有錯，但執行就 crash 了(除非你剛好有幫 Fox 類別實作了 <code>addObject:</code> 方法)。如果改用 <code>instancetype</code> 的話，編譯器就會把問題在編譯階段就抓出來了。</p>

<h2>什麼是 instancetype?</h2>

<p>引用 Clang 文件的一段話：</p>

<blockquote><p>&#8220;instancetype is a contextual keyword that is only permitted in the result type of an Objective-C method&#8221;</p></blockquote>


<p>其實 <code>instancetype</code> 就只是個關鍵字(keyword)，它告訴編譯器回傳型態，讓編譯器可以在編譯階段就有足夠的資訊可以來判斷你寫的程式碼是不是有問題。</p>

<h2>用 instancetype 取代 id?</h2>

<p>在 <a href="https://developer.apple.com/wwdc/videos/">WWDC 2013</a> 的影片(404 - Advances in Objective-C)提到在新版的 SDK 加入了 <code>instancetype</code> 這個型別。其實 <code>instancetype</code> 並不是很新的東西，不過 Apple 在最近推出的 SDK 開始把 <code>id</code> 改換成 <code>instancetype</code>，例如我們隨便打開一個內建的類別的 header，例如 <code>NSArray.h</code> 來看看：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">// 檔案：NSArry.h</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">array</span><span class="p">;</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">arrayWithObject:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">anObject</span><span class="p">;</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">arrayWithObjects:</span><span class="p">(</span><span class="k">const</span> <span class="kt">id</span> <span class="p">[])</span><span class="nv">objects</span> <span class="nf">count:</span><span class="p">(</span><span class="n">NSUInteger</span><span class="p">)</span><span class="nv">cnt</span><span class="p">;</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">arrayWithObjects:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">firstObj</span><span class="p">,</span> <span class="p">...</span> <span class="n">NS_REQUIRES_NIL_TERMINATION</span><span class="p">;</span>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">arrayWithArray:</span><span class="p">(</span><span class="n">NSArray</span> <span class="o">*</span><span class="p">)</span><span class="nv">array</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">init</span><span class="p">;</span><span class="cm">/* designated initializer */</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">initWithObjects:</span><span class="p">(</span><span class="k">const</span> <span class="kt">id</span> <span class="p">[])</span><span class="nv">objects</span> <span class="nf">count:</span><span class="p">(</span><span class="n">NSUInteger</span><span class="p">)</span><span class="nv">cnt</span><span class="p">;</span><span class="cm">/* designated initializeralizer */</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">initWithObjects:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">firstObj</span><span class="p">,</span> <span class="p">...</span> <span class="n">NS_REQUIRES_NIL_TERMINATION</span><span class="p">;</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">initWithArray:</span><span class="p">(</span><span class="n">NSArray</span> <span class="o">*</span><span class="p">)</span><span class="nv">array</span><span class="p">;</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">initWithArray:</span><span class="p">(</span><span class="n">NSArray</span> <span class="o">*</span><span class="p">)</span><span class="nv">array</span> <span class="nf">copyItems:</span><span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nv">flag</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>NSArray 的 initializer 以及一些 class method 的回傳型態都也都是改用 <code>instancetype</code> 了。</p>

<p>所以意思是要用 <code>instancetype</code> 來取得 <code>id</code> 的意思嗎? 其實不是的。</p>

<p>Clang 的文件提到 <code>instancetype</code> 是 &#8220;only permitted in the result type of an Objective-C method&#8221;， 也就是說，<code>instancetype</code> 只能作為回傳值，不能作為參數，像這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">clickAction:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span> <span class="n">sender</span><span class="p">;</span>            <span class="c1">// 這樣寫沒問題</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">clickAction:</span><span class="p">(</span><span class="n">instancetype</span><span class="p">)</span> <span class="n">sender</span><span class="p">;</span>  <span class="c1">// 但這樣寫是不行的</span>
</span></code></pre></td></tr></table></div></figure>


<p>簡單的說，<code>instancetype</code> 主要的目的是為了幫助編譯器更了解你的程式碼，提早在編譯階段就發現問題。</p>

<p>至於之前已經寫好的程式碼需要整個用 <code>instancetype</code> 再重新改寫嗎? 其實也沒必要，不改也不會怎麼樣，因為編譯器本來就會幫 <code>alloc</code>、<code>new</code>、<code>init</code> 之類的方法傳回適當的型別，不過如果是新的專案，倒是建議可以試著在適當的地方開始使用 <code>instancetype</code>。</p>

<p>話說，研究這種有點冷門的東西對 iOS app 的開發雖然不會有直接明顯的幫助，但對整個 Objective-C / Cocoa Framework 可以有更進一步的認識，可以更知道我寫的程式碼到底實際上是怎麼運作的，我個人覺得這樣挺有趣的。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Object, Class and Meta Class in Objective-C]]></title>
    <link href="http://blog.eddie.com.tw/2013/12/05/object-class-and-meta-class-in-objective-c/"/>
    <updated>2013-12-05T01:55:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2013/12/05/object-class-and-meta-class-in-objective-c</id>
    <content type="html"><![CDATA[<p>寫了一陣子的 Objective-C/iOS app，這次讓我們回頭來看點基礎的東西 :)</p>

<h3>什麼是 id?</h3>

<p>在 Objective-C 裡，變數宣告通常得告知編譯器這個變數的型別，例如這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="n">NSArray</span><span class="o">*</span> <span class="n">myArray</span> <span class="o">=</span> <span class="err">@</span><span class="p">[</span><span class="s">@&quot;eddie&quot;</span><span class="p">,</span> <span class="s">@&quot;kao&quot;</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>而在 Objective-C 裡有個特別的型別叫做 <code>id</code>，它可以指向任何物件，像這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="kt">id</span> <span class="n">myObject</span> <span class="o">=</span> <span class="err">@</span><span class="p">[</span><span class="s">@&quot;eddie&quot;</span><span class="p">,</span> <span class="s">@&quot;kao&quot;</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>那這個 <code>id</code> 是什麼? 我們直接來從原始程式碼來找這個 <code>id</code> 的定義。大家可以打開 XCode，然後選擇「File」→「Open Quickly..」，應該可以找到 <code>objc.h</code> 這個檔案，往下捲一點，應該可以找到像下面的這幾行程式碼：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="c1">/// 檔案名稱：objc.h</span>
</span><span class='line'><span class="c1">/// A pointer to an instance of a class.</span>
</span><span class='line'><span class="k">typedef</span> <span class="k">struct</span> <span class="n">objc_object</span> <span class="o">*</span><span class="n">id</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>就照上面這段註解說的，所謂的 <code>id</code> 就是一個「指向一個實例 (instance) 的指針」，而且 <code>id</code> 這個 Struct 的定義本身就有帶一個 <code>*</code>，這也是為什麼你在宣告其它一般物件型別的變數需要加註一個 <code>*</code> 來表示這是一個指標變數，而使用 <code>id</code> 卻不需要的原因。</p>

<h2>什麼是一個物件 (Object)?</h2>

<p>讓我們再從剛剛那個檔案，順蔓摸瓜的繼續看下去..</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="c1">/// 檔案名稱：objc.h</span>
</span><span class='line'><span class="c1">/// Represents an instance of a class.</span>
</span><span class='line'><span class="k">struct</span> <span class="n">objc_object</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">Class</span> <span class="n">isa</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>從這段程式碼可以知道，其實所謂的「物件」，說穿了就只是一個 C 的結構 (C Struct)，而在這個 Struct 裡面只有一個 <code>isa</code> 的指針，指向自己所屬的類別。</p>

<p>再來我們來看看在 Objective-C 裡，到底什麼是一個類別(Class)</p>

<h2>什麼是類別 (Class)?</h2>

<p>繼續來看剛剛的那個檔案：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="c1">/// 檔案：objc.h</span>
</span><span class='line'><span class="c1">/// An opaque type that represents an Objective-C class.</span>
</span><span class='line'><span class="k">typedef</span> <span class="k">struct</span> <span class="n">objc_class</span> <span class="o">*</span><span class="n">Class</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>看得出來其實 <code>Class</code> 本身也是一個 C Struct，再往下看一下這個 <code>objc_class</code> 的定義 (runtime.h)：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="c1">/// 檔案：runtime.h</span>
</span><span class='line'><span class="k">struct</span> <span class="n">objc_class</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">Class</span> <span class="n">isa</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#if !__OBJC2__</span>
</span><span class='line'>    <span class="n">Class</span> <span class="n">super_class</span><span class="p">;</span>
</span><span class='line'>    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">long</span> <span class="n">version</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">long</span> <span class="n">info</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">long</span> <span class="n">instance_size</span><span class="p">;</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">objc_ivar_list</span> <span class="o">*</span><span class="n">ivars</span><span class="p">;</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">objc_method_list</span> <span class="o">**</span><span class="n">methodLists</span><span class="p">;</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">objc_cache</span> <span class="o">*</span><span class="n">cache</span><span class="p">;</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">objc_protocol_list</span> <span class="o">*</span><span class="n">protocols</span><span class="p">;</span>
</span><span class='line'><span class="cp">#endif</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>從上面這段程式碼可以看到，所謂的類別也是一個 C Struct，裡面第一個指針 <code>isa</code> 指向它的所屬類別，第二個指針 <code>super_class</code> 則是指向它的父類別。除此之外還有一些其它的指針，指向例如 instance variables、method list、cache、protocol 等 Struct。</p>

<h2>訊息傳遞 (Message Passing)</h2>

<p>大家在其它 Objective-C 的書上應該常看到，在 Objective-C 的世界裡，方法不像其它程式語言一樣的被直接呼叫，而是透過「訊息傳遞(Message Passing)」方式，像是這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="p">[</span><span class="n">someObject</span> <span class="nl">saySomething:</span><span class="s">@&quot;hello&quot;</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>這裡的 <code>someObject</code> 稱作 <code>receiver</code>，就是接收「訊息」的傢伙，而 <code>saySomething:</code> 就是「訊息」，<code>@"hello"</code> 則是參數。</p>

<p>事實上，在訊息傳遞的過程，當 <code>someObject</code> 這傢伙收到訊息之後，會順著這個物件的 <code>isa</code> 指針找到自己的類別，然後再依照收到的「訊息」去類別的 method list 找出對應的方法。如果在這個類別裡面找到了，就會直接執行它，如果找不到，會再往上一層父類別(super class)找。以上這個流程都是在程式執行過程中(Rumtime)才動態決定的，而不是在編譯(Compile)時期就決定好的。</p>

<p>而這個訊息傳遞的過程畢竟是多做了幾件事，相對感覺會比較耗時，但實際上在程式的執行過程中，一但執行過的方法就會被暫存(cache)下來，下次再收到一樣的訊息的時候就會快得多了。</p>

<p>其實，在 Objective-C 的世界裡，類別本身也是物件，所以你也可以對它「發送訊息」，像是這樣：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="p">[</span><span class="n">NSArray</span> <span class="nl">arrayWithObjects:</span><span class="s">@&quot;eddie&quot;</span><span class="p">,</span> <span class="s">@&quot;kao&quot;</span><span class="p">,</span> <span class="nb">nil</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>看起來就跟在其它程式語言的「類別方法」差不多，但事實上它就是對 <code>NSArray</code> 這個類別發送了 <code>arrayWithObjects:</code> 這個訊息。</p>

<p>接下來我們直接寫一小段程式會比較容易想像：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">// Animal Class</span>
</span><span class='line'><span class="k">@interface</span> <span class="nc">Animal</span> : <span class="nc">NSObject</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">Animal</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Fox Class</span>
</span><span class='line'><span class="k">@interface</span> <span class="nc">Fox</span> : <span class="nc">Animal</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">say</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">Fox</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">say</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;What does the fox say!?&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>上面這段程式碼建立了兩個類別，分別是 <code>Animal</code> 及 <code>Fox</code> ，而且 <code>Fox</code> 繼承自 <code>Animal</code>，而 <code>Animal</code> 類別則是繼承自 <code>NSObject</code> 類別。</p>

<p>不管是「物件」或是「類別」，因為一樣都是物件，所以他們在收到訊息時的反應流程也是一樣的：</p>

<ul>
<li>當對「物件」發送訊息的時候，它會順著這個物件的 <code>isa</code> 指針找到它的所屬類別，然後翻看看這個類別的 method list 有沒有符合的方法可以執行；</li>
<li>當對「類別」發送訊息的時候，它會順著這個類別的 <code>isa</code> 指針找到它的所屬類別(也就是我們待會要說明的 Meta Class)，然後翻看看這個類別的 method list 有沒有符合的方法可以執行。</li>
</ul>


<h2>什麼是 Meta Class?</h2>

<p><code>Meta</code> 這個字我不太懂中文該怎麼翻譯比較好，有人翻譯成「元」，有人翻譯成「後設」，但我個人還是喜歡直接使用 <code>Meta</code> 這個詞就好。</p>

<p>剛剛在看類別的 <code>objc_class</code> 的定義的時候有提到類別的 Struct 裡也有一個 <code>isa</code> 指針，指向它所屬的類別，你可以想像成是它是「類別的類別」，也就是所謂的 <code>Meta Class</code>。</p>

<p>而 Meta Class 其實也是一種類別，所以也跟一般的類別一樣有 <code>isa</code> 跟 <code>super_class</code> 指針&#8230; 所以就可以把這整個的關係用一張圖表來解釋：</p>

<p><img src="http://blog.eddie.com.tw/images/2013/objective-c-object-model.png" alt="image" /></p>

<p>看圖說故事：</p>

<ol>
<li>每個 Class (Fox, Animal, NSObject) 的 <code>isa</code> 指針都指向一個唯一的 Class，這個 Class 稱之為 <code>Meta Class</code>。</li>
<li>每個 Meta Class 的 <code>isa</code> 指針都是指向最上層的 Meta Class (在我們上面那段範例裡，就是 NSObject 的 Meta Class)，而最上層的 Meta Class 的 <code>isa</code> 則是指向自己，形成一個迴路。</li>
<li>每個 Meta Class 的 <code>super_class</code> 指針都是指向它原本類別的 Super Class 的 Meta Class，但最上層的 Meta Class 的 <code>super_class</code> 則是指向 NSObject 類別本身。</li>
<li>最上層的 Class (NSObject)，它的 Super Class 指向 <code>nil</code>。</li>
</ol>


<p>PS: 在 Objective-C 裡有兩種 Root Class(NSObject 跟 NSProxy)，但因為在 Objective-C 裡「大部份」的類別都是 <code>NSObject</code> 的子類別，所以舉例常會說最上層的類別就是 <code>NSObject</code>。</p>

<p>一堆 Class、Super Class、Meta Class 的，有種快打結的感覺了嗎? 其實只要理解上面那張圖片，基本上就不用記這些繞舌的規則了。</p>

<p>但口說無憑，讓我們來寫幾行程式碼驗證一下：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="n">Fox</span><span class="o">*</span> <span class="n">lucky</span> <span class="o">=</span> <span class="p">[[</span><span class="n">Fox</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">lucky</span> <span class="n">say</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// about fox instance</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;the class of lucky is %@, address = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">lucky</span> <span class="n">class</span><span class="p">],</span> <span class="p">[</span><span class="n">lucky</span> <span class="n">class</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// about Fox class</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Fox = %@, address = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">Fox</span> <span class="n">class</span><span class="p">],</span> <span class="p">[</span><span class="n">Fox</span> <span class="n">class</span><span class="p">]);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Fox&#39;s Super Class = %@, address = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">Fox</span> <span class="n">superclass</span><span class="p">],</span> <span class="p">[</span><span class="n">Fox</span> <span class="n">superclass</span><span class="p">]);</span>
</span><span class='line'><span class="n">Class</span> <span class="n">metaClassOfFox</span> <span class="o">=</span> <span class="n">object_getClass</span><span class="p">([</span><span class="n">Fox</span> <span class="n">class</span><span class="p">]);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Fox&#39;s Meta Class = %p&quot;</span><span class="p">,</span> <span class="n">metaClassOfFox</span><span class="p">);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Fox&#39;s Meta Class&#39;s Super Class = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">metaClassOfFox</span> <span class="n">superclass</span><span class="p">]);</span>
</span><span class='line'><span class="n">Class</span> <span class="n">metaMetaClassOfFox</span> <span class="o">=</span> <span class="n">object_getClass</span><span class="p">(</span><span class="n">metaClassOfFox</span><span class="p">);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Fox&#39;s Meta Class&#39;s Meta Class = %p&quot;</span><span class="p">,</span> <span class="n">metaMetaClassOfFox</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// about Animal class</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Animal = %@, address = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">Animal</span> <span class="n">class</span><span class="p">],</span> <span class="p">[</span><span class="n">Animal</span> <span class="n">class</span><span class="p">]);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Animal&#39;s Super Class = %@, address = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">Animal</span> <span class="n">superclass</span><span class="p">],</span> <span class="p">[</span><span class="n">Animal</span> <span class="n">superclass</span><span class="p">]);</span>
</span><span class='line'><span class="n">Class</span> <span class="n">metaClassOfAnimal</span> <span class="o">=</span> <span class="n">object_getClass</span><span class="p">([</span><span class="n">Animal</span> <span class="n">class</span><span class="p">]);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Animal&#39;s Meta Class = %p&quot;</span><span class="p">,</span> <span class="n">metaClassOfAnimal</span><span class="p">);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Animal&#39;s Meta Class&#39;s Super Class = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">metaClassOfAnimal</span> <span class="n">superclass</span><span class="p">]);</span>
</span><span class='line'><span class="n">Class</span> <span class="n">metaMetaClassOfAnimal</span> <span class="o">=</span> <span class="n">object_getClass</span><span class="p">(</span><span class="n">metaClassOfAnimal</span><span class="p">);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Animal&#39;s Meta Class&#39;s Meta Class = %p&quot;</span><span class="p">,</span> <span class="n">metaMetaClassOfAnimal</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// about NSObject class</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSObject = %@, address = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">NSObject</span> <span class="n">class</span><span class="p">],</span> <span class="p">[</span><span class="n">NSObject</span> <span class="n">class</span><span class="p">]);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSObject&#39;s Super Class = %@, address = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">NSObject</span> <span class="n">superclass</span><span class="p">],</span> <span class="p">[</span><span class="n">NSObject</span> <span class="n">superclass</span><span class="p">]);</span>
</span><span class='line'><span class="n">Class</span> <span class="n">metaClassOfNSObject</span> <span class="o">=</span> <span class="n">object_getClass</span><span class="p">([</span><span class="n">NSObject</span> <span class="n">class</span><span class="p">]);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSObject&#39;s Meta Class = %p&quot;</span><span class="p">,</span> <span class="n">metaClassOfNSObject</span><span class="p">);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSObject&#39;s Meta Class&#39;s Super Class = %p&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">metaClassOfNSObject</span> <span class="n">superclass</span><span class="p">]);</span>
</span><span class='line'><span class="n">Class</span> <span class="n">metaMetaClassOfNSObject</span> <span class="o">=</span> <span class="n">object_getClass</span><span class="p">(</span><span class="n">metaClassOfNSObject</span><span class="p">);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;NSObject&#39;s Meta Class&#39;s Meta Class = %p&quot;</span><span class="p">,</span> <span class="n">metaMetaClassOfNSObject</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>輸出結果如下：</p>

<pre><code>What does the fox say!?

the class of lucky is Fox, address = 0x100002260

Fox = Fox, address = 0x100002260
Fox's Super Class = Animal, address = 0x100002210
Fox's Meta Class = 0x100002238
Fox's Meta Class's Super Class = 0x1000021e8
Fox's Meta Class's Meta Class = 0x7fff77cce838

Animal = Animal, address = 0x100002210
Animal's Super Class = NSObject, address = 0x7fff77cce810
Animal's Meta Class = 0x1000021e8
Animal's Meta Class's Super Class = 0x7fff77cce838
Animal's Meta Class's Meta Class = 0x7fff77cce838

NSObject = NSObject, address = 0x7fff77cce810
NSObject's Super Class = (null), address = 0x0
NSObject's Meta Class = 0x7fff77cce838
NSObject's Meta Class's Super Class = 0x7fff77cce810
NSObject's Meta Class's Meta Class = 0x7fff77cce838
</code></pre>

<p>輸出結果可能在每個人的電腦上都不一樣，但從輸出的結果就能證明上面那張圖片的每個類別之間的關係。</p>

<p>要特別注意的是，你可能會覺得直接對類別發送 <code>class</code> 訊息就可以得到該類別的 Meta Class，事實上直接對類別發送 <code>class</code> 訊息只會得到該類別自己。要取得類別的 Meta Class，可以透過 <code>object_getClass</code> 來取得。</p>

<p>以上，希望這篇文章能讓大家對 Objective-C 基本的物件跟類別有更進一步的了解。</p>

<p>個人認為，雖然了解這些知識不見得對 iOS app 的開發有直接的幫助，但至少當在寫一個類別或使用一個物件的時候，會更清楚到底是怎麼一回事。如果有哪邊寫錯，還請前輩先進不吝指點。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[分心 FanXin app]]></title>
    <link href="http://blog.eddie.com.tw/2013/10/18/fanxin-app/"/>
    <updated>2013-10-18T01:55:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2013/10/18/fanxin-app</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2013/fanxin-app.jpg" alt="image" /></p>

<p>今年二月份剛好有機會到朋友的公司幫忙開發 iOS app：「分心 FanXin」。顧名思義，就是一個可以讓你一邊看電視，一邊分心地跟朋友聊劇情的 app。</p>

<p>下載網址：<a href="https://itunes.apple.com/tw/app/fanxin-fen-xin/id545965153?mt=8" target="_blank">https://itunes.apple.com/tw/app/fanxin-fen-xin/id545965153?mt=8</a></p>

<p>但近期因為覺得我家的那兩隻小朋友在長大的速度變好快，覺得好像再這樣忙下去就會錯過小朋友的成長過程了(像今天才看到我家三歲的小男生拿媽媽的化妝品在畫自己的臉)。所以把專案進度做個段落之後，就要回家來養小孩了(沒錯，我就是要從小開始訓練小朋友寫 code 了!)。</p>

<h2>做玩具與做產品的差別</h2>

<p>這回幾乎把一些常見的 iOS app 常用的東西都再磨過一輪。UI customization 當然是免不了的，另外，從 Facebook SDK 到 remote &amp; local notification，從 HTTP API 的串接到 streaming messaging protocol 的訊息處理，從 Core Data 到 NoSQL 等等，甚至也很幸運的遇到了 iOS 7 的 migration，完全體會到做玩具跟做產品的差別。</p>

<p>這個 app 雖然不是全新打造的，但由於舊版的 app 架構有些不適合新改版的功能需求，所以最後幾乎是整個砍掉重練，從無到有手刻了超過三萬五千多行的程式碼(不包含3rd party library)：
<img src="http://blog.eddie.com.tw/images/2013/fanxin-cloc.png" alt="image" />
雖然跟一些大型專案比起來還差很遠，但對我個人來說已是個里程碑，除了提昇了不少寫 code 的手感外，也更了解 Objective-C 跟 Cocoa framework 是怎麼回事。</p>

<p><a href="http://fanxin.tv/">分心團隊</a>雖然是個新創團隊，但裡面的成員都不會太新手，有眼光犀利的UI、UX designer 讓整個 app 看起來很精緻，使用起來也更直覺；有優秀的工程師負責處理 API，也有專門負責行銷及想點子的同事，讓開發人員可以 專心的開發 app；除此之外，還有 Web 平台的開發人員，讓 Web 跟 Mobile 都有一樣的功能。在這短短的八個多月的時間跟大家學到不少。</p>

<h2>徵人啟事</h2>

<p>分心團隊目前仍持續有在徵人，有興趣的朋友歡迎來試試看囉!</p>

<ul>
<li><a href="http://www.104.com.tw/jobbank/custjob/index.php?r=cust&amp;j=5e70436b5a6c3e233c423b1d1d1d1d5f2443a363189j01">徵才頁面</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[HHKB Pro2 鍵盤使用心得]]></title>
    <link href="http://blog.eddie.com.tw/2013/06/29/about-hhkb-pro2/"/>
    <updated>2013-06-29T10:02:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2013/06/29/about-hhkb-pro2</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2013/hhkb-pro2-1.jpg" alt="image" /></p>

<p>我每天的工作是敲打鍵盤之類的文書工作，所以幫自己找一隻順手的鍵盤也是剛剛好的藉口。</p>

<p>對於 HHKB 鍵盤的傳說，很早之前就有所聽聞了。最知名的應該就是 Richard Stallman 用 HHKB 鍵盤搭配百元電腦的那張照片(鍵盤本身比電腦本體還貴!)。我知道它是神器，但我等凡人即使拿了神器還是凡人，不會變成大神。 而且當初看到鍵盤上沒有方向鍵、沒有 <kbd>CTRL</kbd> 鍵跟 <kbd>F1</kbd> ~ <kbd>F12</kbd> 鍵，在台灣也沒什麼機會試打看看手感，最重要的是，它的價錢不便宜，所以大多只是看看而已。</p>

<p>直到前不久去日本參加活動，有在電腦賣場試打了一下，心一橫的也敗了一隻回來，我挑的是白色無刻的版本。</p>

<!-- more -->


<h2>鍵盤設計</h2>

<p>HHKB 鍵盤實在是非常的小一隻，裡面也沒有我另外兩隻 Filco 一樣有加重的鐵板，而且它的 USB 線是可以拆卸的，所以攜帶相當方便。</p>

<p>在鍵盤的配置上，一般鍵盤的 <kbd>ESC</kbd> 鍵是在最左上角，但 HHKB 的 <kbd>ESC</kbd> 鍵就在數字 <kbd>1</kbd> 的旁邊，對 Vim 使用者來說可能算是個福音，因為左手小指頭稍微伸長一下就按得到了。不過對我來說影響不大，因為我很早就習慣用 <kbd>CTRL</kbd> + <kbd>[</kbd> 做為替代方案了。</p>

<p>第二個不習慣的點，是 <kbd>DELETE</kbd> 鍵的位置在 <kbd>ENTER</kbd> 鍵上方，一開始常常會打錯。為什麼這樣設計呢? 其實我也不清楚，反正我現在也都是儘量使用 <kbd>CTRL</kbd> + <kbd>h</kbd> 來替代 <kbd>DELETE</kbd> 鍵。</p>

<p>最後，就是它的 <kbd>~</kbd> 跟 <kbd>|</kbd> 鍵的位置也跟一般鍵盤不一樣，附上一張 HHKB 的鍵盤配置圖：
<img src="http://blog.eddie.com.tw/images/2013/hhkb-layout.png" alt="image" /></p>

<p>HHKB 鍵盤最讓人卻步的，應該就是它沒有方向鍵。雖然沒有直接的方向鍵，但透過 <kbd>fn</kbd> 鍵的組合也是可以打得出來。一開始我也會覺得每次要上下左右之前還得再按一下 <kbd>fn</kbd> 很麻煩，但其實習慣之後也還好，而且對我自己的工作習慣來說，方向鍵使用的機會其實並沒想像中的多。</p>

<p>另外，鍵盤後面另外還有兩個 USB 插槽，剛好解決 MBP 的 USB 接孔不足的問題，像我就是拿來接無線滑鼠：
<img src="http://blog.eddie.com.tw/images/2013/hhkb-pro2-usb-slots.jpg" alt="image" /></p>

<h2>為什麼選無刻?</h2>

<p>因為我想強迫自己在工作的時候把眼睛的視線停留在螢幕上就好，腦袋一邊想，然後手指頭跟著敲打。不過對我來說比較難習慣的還是數字鍵，特別是 <kbd>6</kbd>、<kbd>7</kbd>、<kbd>8</kbd>、<kbd>9</kbd> 這種在鍵盤比中間的數字，只要手指頭擺放鍵位的習慣不好，常常就會打錯，我到現在還沒辦法每次都能正確的打對我的電話號碼。</p>

<h2>替代組合鍵</h2>

<p>雖然 HHKB 為了縮小體積而拿掉了一些比較方便的鍵帽，不過還好在我平常工作的 Mac OS 有一些方便的替代組合鍵可以用：</p>

<ul>
<li><kbd>CTRL</kbd> + <kbd>h</kbd> 刪除游標所在的前一個字元</li>
<li><kbd>CTRL</kbd> + <kbd>d</kbd> 刪除游標所在的後一個字元</li>
<li><kbd>CTRL</kbd> + <kbd>k</kbd> 刪除游標之後該行的所有字元</li>
<li><kbd>CTRL</kbd> + <kbd>n</kbd> 移到游標到下一行</li>
<li><kbd>CTRL</kbd> + <kbd>p</kbd> 移到游標到上一行</li>
<li><kbd>CTRL</kbd> + <kbd>a</kbd> 移到游標到行頭</li>
<li><kbd>CTRL</kbd> + <kbd>e</kbd> 移到游標到行尾</li>
</ul>


<p>有這些組合鍵，可以減低不少沒有方向鍵以及 <kbd>DELETE</kbd> 鍵位置不同的的不適感。</p>

<h2>手感</h2>

<p>我不太會描述這種「感覺」的東西，感覺這回事只得靠自己來感覺了。HHKB Pro2 是無接點靜電容量式鍵盤，我只能大概形容它打起來有點像紅軸但又少了機械鍵盤的那麼明顯的清脆感，鍵盤打起來手感是真的不錯，特別是空白鍵打起來很穩。空白鍵對我來說很重要，因為空白鍵打的機會很高，之前打過一隻空白鍵會晃而且有雜音的機械鍵盤，整個感覺就差很多。</p>

<h2>使用</h2>

<p>平常使用鍵盤大多是就放在桌上，或是大腿上，如果空間不夠，我也會學 Richard Stallman 一樣把鍵盤架在筆電上：
<img src="http://blog.eddie.com.tw/images/2013/hhkb-pro2-with-mbpr.jpg" alt="image" />
可惜沒辦法架在原本的鍵盤上(會壓到筆電本身的鍵盤，據說 MBA 11&#8221; 的可以，不過我沒試過)</p>

<p>另外，我也很騷包的從友人那邊取得了一條會發光的 mini USB 線：<iframe width="420" height="315" src="http://www.youtube.com/embed/hEepCFj7vKc" frameborder="0" allowfullscreen></iframe></p>

<h2>小結：</h2>

<p>MBP 的鍵盤還好，但 MBA / MBPR 的鍵盤也許因為設計的關係，鍵盤比 MBP 要再淺個零點幾公分，打起來的手感我不太習慣，外接鍵盤之後就比較沒這個困擾了。 雖然一開始不太習慣 HHKB 的鍵盤配置，不過一切真的都是習慣就好了。</p>

<p>我差不多一個多禮拜就習慣它了，只是，HHKB 鍵盤跟 Vim 一樣，都是那種只要習慣它之後就沒辦法習慣別人的東西。雖說是差不多習慣了，但還是得多練習更熟練一些，才不會愧對這隻特別而且有趣的鍵盤 :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RubyKaigi 2013]]></title>
    <link href="http://blog.eddie.com.tw/2013/06/14/rubykaigi-2013/"/>
    <updated>2013-06-14T01:55:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2013/06/14/rubykaigi-2013</id>
    <content type="html"><![CDATA[<p class="info">本篇文章已刊載於 <a href="http://www.openfoundry.org/tw/foss-forum/9002-rubykaigi-2013" target="_blank">OpenFoundry 電子報自由專欄</a>，刊登之內容由專業的 OpenFoundry 團隊潤稿，此篇為原文。</p>


<p>今年日本的 <a href="http://rubykaigi.org/2013" target="_blank">RubyKaigi 2013</a> 在 5/29(四)、5/30(五)、6/1(六)舉辦，議程是雙軌同時進行，共計有超過五十場演講及十場 Lightning Talk，並包括三場主題演講 (Keynote)，跟上一屆一樣也是三天。這次有超過 500 位 Ruby 開發者參加，其中有超過 100 位是從國外來的，這樣的規模短期內在台灣可能還是沒辦法達到(全台灣真的有在用 Ruby 工作的開發者加起來總數說不定都還不到 500 人)。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-opening.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<!-- more -->


<p>門票的部份比往年貴不少，上一屆的門票是 6,000 日幣，而今年沒有折扣的票種是 35,000 日幣(<a href="http://rubykaigi.doorkeeper.jp/events/2980" target="_blank">報名網站</a>)。我運氣很好，因為演講投稿有被大會接受，所以省下了門票錢。</p>

<p>要特別一提的是，RubyKaigi 的門票票種除了一般票、學生票以及早鳥票之外，還有給地區 RubyKaigi 的主辦單位的優待票，還有曾經來參加 Rails Girls 的朋友及主辦單位。另外，即使投稿沒上的，也有部份的優惠。最有趣的是 Ruby Committer 票種，並不是成為 Committer 就可以理所當然的免費參加，要有超過 200 次 commit 數的才是免費，低於這個數字的還是得乖乖買票進場。</p>

<h2>Pre-event</h2>

<p>在 RubyKaigi 正式開始前一天晚上，<a href="http://qwik.jp/asakusarb/" target="_blank">Asakusa.rb</a> 主辦了一個暖身活動(<a href="http://www.tokyorubyistmeetup.org/events/3954" target="_blank">報名網站</a>)，地點在日本相當知名的食譜網站公司 <a href="http://cookpad.com/" target="_blank">Cookpad</a>。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-cookpad.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>現場來了許多只能在網路上才能見到的高手，而且連 Ruby 的老爸 <a href="https://twitter.com/yukihiro_matz" target="_blank">Matz</a> 也來了。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-matz.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>現場氣氛十分熱絡，Cookpad 的廚師還親自動手作飯給大家吃，真的是太切題了。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-cookpad-meal.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h2>RubyKaigi</h2>

<h3>地點</h3>

<p>RubyKaigi 的舉辦地點是在日本東京的國際交流館：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-location.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>主會議廳有上下兩層樓：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-architecture.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>本次大會主席角谷信太郎(<a href="https://twitter.com/kakutani" target="_blank">@kakutoni</a>)開場就說到：「那些平常只有在教課書裡才會出現的人物，現在很可能就坐在你身邊」。高手、大神們出沒的密度，遠超過我的想像。</p>

<h3>T-shirt</h3>

<p>大會發給每位會眾一人一件 T-shirt，擺放在報到處，會眾自己報到的時候就自己拿一件，而我因為講者的身份，我又多賺到一件。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-t-shirt.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>可惜大會只提供 M 跟 L 尺寸，我太胖了，L 號的穿不太下..</p>

<h3>名牌</h3>

<p>往年聽說就是用名信片大小的空白名牌讓大家自己手寫，不但可以省下印刷的時間跟成本，而且還可讓大家發揮自己的創意。另外，裝名牌的袋子背後的有個拉鏈，裡面可以放一些名片，這樣要跟現場的朋友交換名片的時候就方便多了。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-nametag.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h3>行動應用</h3>

<p>大會有提供手機版的 App 供大家下載 (<a href="https://itunes.apple.com/us/app/irubykaigi13/id648686610?mt=8" target="_blank">iRubyKaigi13</a>)。App 的作者是位資深但非常客氣的前輩，為了應景特地採用 RubyMotion 製作，有這個 App 在現場要查詢議程或講師個人資料的時候相當方便。</p>

<h3>訊息牆</h3>

<p>在演講廳講台旁邊，設立了兩道訊息牆，一邊是來自 Twitter 的資料，另一邊則是來自 IRC。當沒有同步翻譯的的時候，訊息牆會貼心的出現善心人士的即時文字翻譯。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-message-wall.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h3>RubyFriends</h3>

<p>網址：<a href="http://rubyfriends.com/" target="_blank">http://rubyfriends.com/</a></p>

<p>Ruby 開發者(通常又稱 Rubyist)大多有使用 twitter 的習慣，只要 twitter 發文的內容裡有標記 #rubyfriends 這個 tag 就會被拉進來，並且在現場播放。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-projector.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>我本來以為播放的是超薄的電視機，後來才知道原來用投影機加上 Android Smart TV 的組合就能做出這樣的效果，效果很不錯，而且成本比想像中的便宜 (<a href="http://hmsk.hatenablog.com/entry/2013/06/02/202411" target="_blank">參考資料來源</a>)。</p>

<h3>Ruby 時計</h3>

<p>網址：<a href="http://rubyistokei.herokuapp.com/" target="_blank">http://rubyistokei.herokuapp.com/</a></p>

<p>參考 uniqlo 的 &#8220;UNIQLOCK&#8221; 概念製作的時鐘，目的是希望讓每位前來參加的 Rubyist 都有出現在螢幕上的機會，讓大家更有參與感。加照片的方式也很簡單，就自己直接 fork 一份指定的 <a href="https://github.com/darashi/rubyistokei" target="_blank">github repository</a>，加完照片資訊後發 pull request 就行了，這對習慣使用 git 做為版控工具的 Rubyist 們來說相當方便，也很切題。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-rubyistokei.jpg" alt="image" /></p>

<h3>世界 Rubyist Sticker</h3>

<p>RubyKaigi 的會眾來自世界各地，這個設計也可以讓與會者更有參與感。台灣雖然不大，但我們這回可是來了五、六個人，當然一定要去衝一下人氣：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-world-sticker.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h3>塌塌米</h3>

<p>如果你不想聽議程，或是想到外面透透氣，又或是在會場見到許久不見的好友想好好聊一下，在會議廳外面亦備有塌塌米可以隨時坐下來休息或工作，再走過去幾步就有 Microsoft 提供的免費飲料：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-tatami-1.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>中午用餐時間塌塌米則轉變成野餐型式：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-tatami-2.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h3>講師</h3>

<p><a href="http://rubykaigi.org/2013/speakers" target="_blank">講者名單</a>裡面就有 16 位 Ruby Core Committer，陣容相當豪華，小弟有幸能跟這些講師排在一起，真的是有些心虛。</p>

<h3>議程</h3>

<p>三天共計有三場主題演講(Keynote)，四十餘場一般演講以及十場 Lightning Talk，二軌議程同時進行。身為地主國而且又是 Ruby 之父的 Matz 當然是免不了一定要來一場 Keynote 的：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-matz-keynote.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>至於其它精彩內容也不需要多做介紹，直接參考 <a href="http://rubykaigi.org/2013/schedule" target="_blank">RubyKaigi 議程</a>頁面會得到更多的資訊。順便厚臉皮的來偷偷廣告一下<a href="http://blog.eddie.com.tw/2013/06/05/code-reading-in-rubykaigi2013/" target="_blank">我自己的主題</a>。</p>

<h3>演講</h3>

<p>在 RubyKaigi 沒有司儀、沒有議程主持人，也沒有講者或主題的簡介或開場，直接自己上台，接上投影機自己喊開始，全部採「自助式」的方式進行。講者自己控制時間，時間到就自己下台換下一位準備上台，相當有趣。</p>

<p>演講內容只有日文跟英文兩種選擇。日文演講的議程，現場有提供日翻英同步口譯，但英文演講則沒有提供，因為大會期望與會者都應該聽得懂英文。</p>

<h3>Lightning Talk</h3>

<p>每個人只有五分鐘的時間，而且必須用英文演講。時間一到旁邊的「ドラ娘」會敲鑼，並將強制中斷投影機訊號：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-dora.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>常參加國內技術研討會的朋友對 LT 應該不陌生，很可惜大家時間都控制得很好，十個 LT 裡只有一個被拔線。</p>

<h3>Ruby Committer v.s. the World</h3>

<p>Ruby 不愧是發源自日本的程式語言，平常要有機會可以跟 Ruby Committer 近距離接觸可能沒那麼容易，這次活動議程裡有一場叫做「Ruby Committers vs. the World」，就是請這些 Committer 們全部一起上台跟大家互動，或是討論 Ruby 之後的方向。一口氣看到台上大概二、三十位的 Ruby Core Committer 排排坐，雖然他們討論的內容是日文我沒能全部聽懂(這個時段沒有同步翻譯)，但依舊感到十分熱血。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-ruby-committers.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h3>TRICK 2013</h3>

<p>網址：<a href="https://sites.google.com/site/trickcontest2013/" target="_blank">https://sites.google.com/site/trickcontest2013/</a></p>

<p>這一個小時的議程我印象非常深刻，因為這是一場我覺得非常「變態」的議程。</p>

<p>請不要誤會，這裡的「變態」是稱讚意味。TRICK 這個比賽並不是要寫出什麼偉大的程式，而是希望參賽者在限定的檔案大小內，儘可能使用 Ruby 神奇或鮮為人知的技巧來寫程式。每個得獎作品，真的都非常變態，讓現場的大家驚嘆怎麼會有人想得出來把 Ruby 寫成這樣。</p>

<p>評審陣容同樣也是非常豪華：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-trick-judges.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h3>Official Party</h3>

<p>Official Party 是在第二天的晚上舉行，地點就在會場附近，活動由 Github 贊助，每個人都可以自由參加。加上因為我自己的演講結束了，輕鬆很多，可以放心大膽的吃吃喝喝，也在現場用我破破的英文認識不少日本朋友。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-official-party.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h3>書商</h3>

<p>近年國內的技術研討會也都有書商的出現，RubyKaigi 則是請淳久堂在現場賣書。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-books.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>有趣的是，淳久堂帶來的這些書，書的作者本人幾乎都有在現場，買完書可以馬上厚臉皮的找作者簽名，相當方便。</p>

<h3>贊助商</h3>

<p>打開 RubyKaigi 網站的<a href="http://rubykaigi.org/2013/sponsors" target="_blank">贊助商列表</a>，據長期待在日本的友人說，這個贊助商列表幾乎都是目前日本一線的軟體公司，在不太重視軟體產業的台灣，這大概是很難看到的畫面了。</p>

<p>除了現金贊助之外，也有一些其它的物資贊助，例如，Heroku 贊助大會三天活動的便當、Microsoft 讓大家在會場有免費的飲料可以喝，:DeNA 贊助現場的 WiFi，Ricoh 贊助現場的投影相關設備，Github 則是贊助 Official Party。</p>

<p>不得不提一下，這回大會的便當不錯吃，而且還挺高級的(據說是日本知名的燒肉便當)：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-heroku-bento.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h2>RubyHiroba (Hiroba日文為&#8221;廣場&#8221;意思)</h2>

<p>這個活動是接在 RubyKaigi 的隔天，需要報名，但免費參加的活動。活動在日本 Microsoft 舉辦：
<img src="http://blog.eddie.com.tw/images/2013/rubyhiroba-microsoft.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>令我有些意外，原來日本 Microsoft 對 Ruby 有這麼多的贊助，除了前面提到贊助 RubyKaigi 的免費飲料外，也提供 RubyHiroba 的場地使用，這在台灣可能比較少見。</p>

<p>不愧是大公司，雖然這只是一個角落的照片，還是可以看得出來工作環境相當不錯：
<img src="http://blog.eddie.com.tw/images/2013/rubyhiroba-env.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>照片右下角不小心入鏡的正是 Ruby 的核心成員之一，Rubygems 跟 RDoc 的維護者 <a href="https://twitter.com/drbrain" target="_blank">Eric Hodel</a>。</p>

<p>上網回答問題的話(Ruby 程式相關的問題，網址：<a href="https://codeiq.jp/ace/ramen_burger/q330" target="_blank">https://codeiq.jp/ace/ramen_burger/q330</a>)，中餐可以得到一份&#8221;拉麵漢堡&#8221;。</p>

<p>另外，活動也有製作很可愛的貼紙：
<img src="http://blog.eddie.com.tw/images/2013/rubyhiroba-stickers.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>基本上 RubyHiroba 並沒有任何即定的議程，跟 RubyKaigi 比起來相對比較輕鬆。除了很多的 Lightning Talk 之外，在這個「廣場」的各個角落有一些同好會的聚集(例如 dRuby 或是地區 Ruby 社群)，，如果不想參與，也可以自己找個角落坐下來寫寫程式，或是去跟偶像們搭訕、請益。我在現場還跟著一位前輩學著折了紙做的紅寶石：
<img src="http://blog.eddie.com.tw/images/2013/rubyhiroba-paper.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>可惜我的日文能力太差，不然應該還可以認識更多的新朋友。</p>

<h3>Rails Girls</h3>

<p>網址：<a href="http://railsgirls.com" target="_blank">http://railsgirls.com/</a></p>

<p>Rails Girls 在全世界好幾個地方都有分支，成立的目的是希望可以給女性提供一個技術交流、學習的管道，而且並不一定限定只學習 Rails。</p>

<p>Rails Girls Tokyo 在 RubyHiroba 也有一個角落，一開始我本來以為這會是台上講師講課，然後其它人坐在台下聽的方式進行，後來經由 organizer <a href="https://twitter.com/yotii23" target="_blank">Yuki Torii</a> 的說明才知道，原來她們並不一定每次都會像在學校&#8221;上課&#8221;的形式，反而是由一個教練(Coach)帶一到兩位學員進行小班制教學，以維持較好的學習品質。</p>

<p><img src="http://blog.eddie.com.tw/images/2013/railsgirls-1.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a>
<img src="http://blog.eddie.com.tw/images/2013/railsgirls-2.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a>
<img src="http://blog.eddie.com.tw/images/2013/railsgirls-3.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a>
<img src="http://blog.eddie.com.tw/images/2013/railsgirls-4.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a>
<img src="http://blog.eddie.com.tw/images/2013/railsgirls-5.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<h2>心得</h2>

<p>日本不愧是 Ruby 的發源地，不僅與會的 Ruby Committer 數量多，而且有一種整個日本 Ruby 圈在這個星期都動起來的感覺。除了地區社群的人也出現在這邊宣傳之外，整個星期除了 RubyKaigi 本身三天的行程之外，前後或晚上都有活動，幾乎可以說是「Ruby 週」了。</p>

<p>除了 RubyKaigi 這種年度大型的聚會外，日本<a href="http://regional.rubykaigi.org/" target="_blank">地區性的 Ruby 社群</a>也相當活躍，例如 <a href="http://qwik.jp/asakusarb/" target="_blank">Asakusa.rb</a>、<a href="http://qwik.jp/okinawarb/" target="_blank">okinawa.rb</a> 等社群，各有各的活動跟當地特色。</p>

<p>在 RubyKaigi，資深前輩或高手出現的密度，真的可以用滿地都是來形容。我沒誇張，除了 Ruby Core Committer 之外，我大概書架上所有的日文 Ruby 相關書籍的作者我都遇到本人了(我還跟 Ruby Hacking Guide 一書的作者青木峰郎握到手了)，而且這些高手們都十分的客氣。我在會場看到我的偶像 <a href="https://twitter.com/tenderlove" target="_blank">Aaron Patterson</a>，就馬上厚臉皮的衝上前去拍照：
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-me-and-aaron.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>可以跟這麼一大群來自各地而且喜歡 Ruby 而且厲害的朋友聚在一起，雖然彼此說著不同國家的語言，但仍有著 Ruby 這個共同的語言，溝通起來並沒想像中的困難。</p>

<p>話說回來，以我自己曾經參加過的幾個程式語言相關的技術研討會來說，Ruby 相關的技術研討會似乎算是相對比較國際化的。就以台灣在 2012 年底舉辦的 <a href="http://rubyconf.tw/" target="_blank">RubyConf Taiwan</a> 來說，就有共計 10 個國家的人前來參加。</p>

<p>另外，關於活動贊助這件事，我自己曾主辦過一些中、小型活動，知道贊助一向都是活動最麻煩的事。以 RubyKaigi 的贊助來說，即使是最大贊助商，也只有在 Keynote 之前上台的幾分鐘的致詞(sponsor appeal)，或者是換得一場五分鐘的 Lightning Talk。將贊助跟議程分開，我個人覺得這是很棒的事。我認為 Keynote (主題演講，日文稱做&#8221;基調講演&#8221;) 是整場活動的主軸，如果因為贊助而出售給贊助商，贊助商很可能會因為為了推廣自家產品而讓主題演講的主軸有所偏差，我想這是主辦單位跟會眾們所不願樂見的。</p>

<p>雖然這回 RubyKaigi 的門票不算太便宜，但我覺得這樣三天的活動非常值得，2014 年再舉辦的話，我一定會再報名參加。
<img src="http://blog.eddie.com.tw/images/2013/rubykaigi-2014.jpg" alt="image" />
photo by <a href="https://twitter.com/eddiekao" target="_blank">@eddiekao</a></p>

<p>最後，感謝 RubyKaigi 的籌辦團隊，給我們這群喜愛 Ruby 的人帶來了一個這麼好的活動，辛苦了。
<span class="translate">
At last, thank you RubyKaigi team, you gave us a AWESOME conference, お疲れ様です!
</span></p>

<p class="info">因為我英文不好，日文也不會，所以如果有善心人士願意幫忙將本文翻譯成英文或日文，歡迎在底下留言，或是直接與我聯繫亦可 :)
<span class="translate">I&#8217;m not good at English nor Japanese, if anyone would like to translate this post into English or Japanese version, feel free to comment here or just contact with me :)</span>
</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Code Reading @ RubyKaigi 2013]]></title>
    <link href="http://blog.eddie.com.tw/2013/06/05/code-reading-in-rubykaigi2013/"/>
    <updated>2013-06-05T01:55:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2013/06/05/code-reading-in-rubykaigi2013</id>
    <content type="html"><![CDATA[<p>很高興這次能有機會到日本參加 <a href="http://rubykaigi.org/2013" target="_blank">RubyKaigi 2013</a>，我分享的題目是：&#8221;<a href="http://rubykaigi.org/2013/talk/S41" target="_blank">Code Reading, Learning More about Ruby by Reading Ruby Source Code</a>&#8220;，算是個滿冷門的題目，主要是分享我自己從閱讀 Ruby 原始程式碼中學習到的一些經驗。不過當天還有不少朋友來捧場，讓場子看起來不會太冷清，真是太意外了(其實我也搞不清楚到底有多少人，我當時已經緊張到沒辦法算數了)。<br />
<span class="translate">Really glad to go to Japan and join the <a href="http://rubykaigi.org/2013" target="_blank">RubyKaigi 2013</a>, the topic of my talk is &#8221;<a href="http://rubykaigi.org/2013/talk/S41" target="_blank">Code Reading, Learning More about Ruby by Reading Ruby Source Code</a>&#8221;, which I don&#8217;t think it&#8217;s a popular topic, and it&#8217;s about my experience while reading Ruby source code. Thanks to those friends who are willing to come to my talk.(Actually I was too nervous to count how many people already)</span></p>

<p>在進入主題之前，我問大家有多少人曾經來過台灣，結果在場有十來個人舉手，就以現場人數的比例來說不算少。<br />
<span class="translate">
Before I jump into my topic, I asked everyone how many of you have been to Taiwan before, to my surprise, there&#8217;re more than 15 people raised their hand, which is about 20% of the attendees in this hall(I think).</span></p>

<p><a href="https://speakerdeck.com/eddie/code-reading" target="_blank"><img src="http://blog.eddie.com.tw/images/2013/rubykaigi-code-reading.jpg" alt="image" /></a>
<a href="https://speakerdeck.com/eddie/code-reading" target="_blank">View on Speaker Deck</a> | <a href="https://speakerd.s3.amazonaws.com/presentations/0186a390abc5013057536ee43d4d4638/Code_Reading.pdf" target="_blank">Download PDF</a></p>

<p>雖然之前有一些些上台演講的經驗，但這是第一次出國演講，而且還是全程用英文演講，我知道有很多的大神甚至 Ruby Committer 就坐在台下，所以我相當緊張。我那個「上台的前一天不會睡」的魔咒果然還是依舊存在，所以演講當天凌晨四點，我拿著筆電到飯店的大廳練習對著空氣講，練到早上七點，但還是覺得不夠穩。<br />
<span class="translate">
Although I have a some experience about having public speech, but it&#8217;s my first time to have a presentation abroad and do my speech in English, and I also know there might be lots of awesome rubyists sitting there, including some Ruby core committer, so I really feel nervous. And I have a curse that &#8220;I won&#8217;t sleep if I have a public presentation on the next day&#8221;, so I practiced in the lobby of the hotel from 4 A.M. to 7 A.M., but still not stable enough.
</span></p>

<p>我的演講廳是小間的，所以壓力有稍微小一點點。<br />
<span class="translate">
My presentation hall is the smaller one, so my pressure is also slightly smaller, too.
</span></p>

<p>為了怕現場出包，所以在 code review 展示的部份我是用預錄的，不過事後想想好像直接現場操作比較容易掌控時間<br />
<span class="translate">
I think I might make some mistakes while presenting, so I recorded the code review demo in advance, but I think the real live demo might be easier for me to control time.
</span></p>

<p>上午的演講結束後，下午發生的小插曲讓我抖了好大一下。我在演講內容裡有提到一些在 Ruby 的原始碼裡面有一些小地方的命名不太優，當下大家笑得很開心，雖然娛樂效果達到了，但我其實也有點擔心會不會有什麼不好的副作用。結果上午的講場結束，下午就看到<a href="https://twitter.com/_zzak/status/340391416314331136" target="_blank">這則</a>：<br />
<span class="translate">
After finishing my talk, there&#8217;s something surprised me. In my speech, I mentioned some interesting naming in the Ruby source code just for fun. I know it might be entertaining but still a little worried about if there would be any bad consequence. Then in the afternoon, I saw this <a href="https://twitter.com/_zzak/status/340391416314331136" target="_blank">tweet</a>:
</span></p>

<p><img src="http://blog.eddie.com.tw/images/2013/rubykaigi-zzak.png" alt="image" /></p>

<p>哇!! 我有嚇到的感覺了，不過因為我個人覺得這樣好像有些失禮，所以當晚的 Official Party，我就親自去跟 @nobu 說聲不好意思，希望沒有造成他的困擾。其實我也是想趁這個機會認識一下只有在網路上才能看得到的傳說大神，而且他好像一點也不在意。<br />
<span class="translate">
Wow! That&#8217;s really really surprised me!! and I don&#8217;t know if this would cause any trouble for committer, so I went to @nobu and said sorry to him on the official party in the night, and hope didn&#8217;t cause extra trouble for him. In fact, I went to him also want to know him by this chance, and actually he didn&#8217;t mind at all.
</span></p>

<p>第三天的議程，我本來就打算要來聽 <a href="https://twitter.com/saturnflyer" target="_blank">Jim Gay</a> 的主題(他是 <a href="http://www.clean-ruby.com/" target="_blank">Clean Ruby</a> 一書的作者 )，沒想到坐下來沒多久竟然看到自己的名字跟前一天講的東西出現在投影片上：<br />
<span class="translate">
In the last day, I was planning to attend <a href="https://twitter.com/saturnflyer" target="_blank">Jim Gay</a>&#8217;s talk, whihc is the author of the book &#8221;<a href="http://www.clean-ruby.com/" target="_blank">Clean Ruby</a>&#8221;. After sitting in the hall, I suddenly found my name was quoted in the slide:
</span></p>

<p><img src="http://blog.eddie.com.tw/images/2013/rubykaigi-jim-gay.jpg" alt="image" /></p>

<p>再度有被嚇到的感覺。<br />
<span class="translate">
Yes, Supprised me again.
</span></p>

<p>活動結束後，RubyKaigi 2013 的頭目角谷<a href="https://twitter.com/kakutani/status/341202764472406017" target="_blank">也推了一篇</a>：<br />
<span class="translate">
the Organizing Director of RubyKaigi 2013 Shintaro Kakutani also <a href="https://twitter.com/kakutani/status/341202764472406017" target="_blank">tweeted this</a>:
</span></p>

<p><img src="http://blog.eddie.com.tw/images/2013/rubykaigi-kakutani.png" alt="image" /></p>

<p>再次看到自己的名字被提到，有些驚訝也有些不好意思，不過這個&#8221;Conference-Driven Development(CDD)&#8221; 聽起來好像不錯，而且我喜歡 &#8220;RubyKaigi made Ruby Better&#8221;，如果有朝一日我有能力，我也希望可以多貢獻一些心力。<br />
<span class="translate">
I feel surprised again and also little embarrassing, but the &#8220;Conference-Driven Development(CDD)&#8221; sounds workable, and I love the &#8220;RubyKaigi made Ruby Better&#8221;, I hope I can do more contributions to Ruby and this community someday if possible.
</span></p>

<p>感謝高井さん(<a href="https://twitter.com/takai" target="_blank">@takai</a>)幫我拍的照片，讓我在 <a href="http://rubyistokei.herokuapp.com/" target="_blank">Rubyist 時計</a>上也可以有一張漂亮的照片。<br />
<span class="translate">
Thanks to Naoto Takai(<a href="https://twitter.com/takai" target="_blank">@takai</a>) to take a photo for me so that I can have a nice picture on the <a href="http://rubyistokei.herokuapp.com/" target="_blank">Rubyist Tokei</a>.
</span></p>

<p><img src="http://blog.eddie.com.tw/images/2013/rubykaigi-rubyist-clock.jpg" alt="image" />
photoed by <a href="https://twitter.com/takai" target="_blank">@takai</a></p>

<p>這趟日本之行有學習到不少東西，收獲很多，會在接下來的幾篇文章介紹。最後，有講的不好的地方，還請多多指教。<br >
<span class="translate">
Anyway, I learned a lot on this trip to Japan, and I&#8217;ll write them down in next blog posts. At last, if there&#8217;s any bad or something wrong about my speech, please feel free to comment.
</span></p>

<p>Thank you all, RubyKaigi team, you&#8217;re all AWESOME!</p>
]]></content>
  </entry>
  
</feed>
