<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

  <title><![CDATA[高見龍]]></title>
  
  <link href="http://blog.eddie.com.tw/" />
  <updated>2012-02-22T04:44:47+08:00</updated>
  <id>http://blog.eddie.com.tw/</id>
  <author>
    <name><![CDATA[高見龍]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/aquarianboy" /><feedburner:info uri="aquarianboy" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title type="html"><![CDATA[Ruby Certified Programmer]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/qIcDG1bV35g/" />
    <updated>2012-01-18T17:57:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2012/01/18/i-am-ruby-certified-programmer</id>
    <content type="html"><![CDATA[<p>今天下午我去參加了Ruby的認證考試，運氣不錯，過了。
<img src="http://blog.eddie.com.tw/images/2012/ruby_certifiy_passed.jpg" alt="image" /><br /></p>

<h2>為什麼要去考這個?</h2>

<p>其實當初目的很單純，只是想說即然我現在也都有靠Ruby在吃飯了，再加上這天剛好我要外出一整天在台北市閒晃，就報名順路去考了。</p>

<h2>報名</h2>

<p><a href="http://www.ruby-assn.org/en/certification.htm">Ruby Association</a>的網站可以找到相關訊息以及報名方法，台灣幾家比較大的電腦補習班都可以考。</p>

<p>考試時間是90分鐘，共有50道選擇題(單、複選都有)。英文出題，滿分100分，75分才算及格。英文出題其實不用怕，畢竟不是像托福要考你英文程度的，所以英文題目的敘述不會用太難的字。</p>

<p>喔，忘了說，報名費是150塊美金。</p>

<h2>心得</h2>

<p>我差不多30分鐘就寫完了，剩下的時間再重頭全部檢查一次。</p>

<p>可能我運氣好吧，除了幾題陷阱題之外，遇到的題目都不算太難。不過我覺得這考試感覺有點像在考對API的記憶力，真的需要花腦筋想的題目不多。有些API在實務上並不常用到，所以..我不覺得只要平常有在寫就有辦法通過考試，特別是只有在寫Rails的話，不特別準備一下可能過不了的(畢竟是Ruby認證，不是Rails認證啊)。</p>

<p>準備方向，就.. 常常練習動手寫是基本一定要的(不然我想弄這個證照也沒什麼意義吧)，然後在考前再把幾個重要的Class、Module的API&#8221;全部&#8221;看過一次，應該就差不多了。我運氣不錯，八十幾分低空飛過(這也表示我還不夠熟)。</p>

<h2>結論</h2>

<p>也許您會好奇，Ruby證照能幹嘛? 到時候拿去貼滷味攤嗎? 老實說，這對我來說並沒什麼實質用途，我不會因為有多這張認證而加薪、案子變多，或是被大公司挖角。</p>

<p>至於&#8221;證照有用/無用&#8221;的討論，網路上已經很多了，那也不會是我關心的重點。我去報名認證考試只是單純的想多一張獎狀而已(小時候成績不好，所以家裡牆壁上沒幾張獎狀，所以當年Adobe的Flash Developer跟Linux的LPI認證也是這樣來的)，順便測試一下自己對Ruby的熟悉程度罷了 :)</p>

<p><img src="http://blog.eddie.com.tw/images/2012/ra_certified.jpg" alt="image" /><br />
總之，小徽章一枚手入 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2012/01/18/i-am-ruby-certified-programmer/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Heroku ─ Ruby 程式語言的最佳雲端環境]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/mVVVtzU25rU/" />
    <updated>2012-01-06T11:11:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2012/01/06/heroku-the-best-cloud-platform-on-ruby-language</id>
    <content type="html"><![CDATA[<p class="info">本篇文章已刊載於<a href="http://www.openfoundry.org/tw/tech-column/8573-heroku-the-best-cloud-platform-on-ruby-language" target="_blank">OpenFoundry電子報技術專欄</a>，刊登之內容由專業的OpenFoundry團隊潤稿，此篇為原文。</p>


<p>你曾經用Ruby on Rails開發網站，但在國內找不到可以用的主機空間嗎? 或者你是新創公司，但初期還沒足夠資金投資在伺服器的硬體設備上嗎? 又或是沒有專職的MIS幫你管理伺服器嗎? 讓我們來看看Heroku吧!</p>

<h1>簡介</h1>

<p>用Ruby on Rails開發網站很快、很方便，但在台灣比較麻煩的是可以租用的主機空間並不好找，如果要自己架一台成本又太高，而且也有一定的技術門檻。目前市面上有不少PasS(Platform As A Service)的解決方案，例如Amazon的<a href="http://aws.amazon.com/">AWS(Amazon Web Services)</a>雖然也是個不錯的解決方案，但還是得花一些時間想辦法安裝、設定到可以執行Rails的環境。如果你不想這麼麻煩，<a href="http://www.heroku.com/">Heroku</a>就是個很不錯的解決方案。不只是Ruby on Rails的程式，任何Rack程式都可以在Heroku執行(包括Ruby on Rails跟Sinatra都沒問題)。</p>

<h1>費用及效能</h1>

<p>選擇主機最在乎的，不外乎是費用及效能這兩件事。Heroku最讓人喜愛的地方之一，就是它有提供免費的額度可以用，網站空間部份，每個專案的限制是100MB，這對一般的小型的專案來說還滿夠用的；資料庫的部份，每個專案的資料庫大小限制則是5MB，而且有SQLite、MySQL、PostgreSQL可以選用。</p>

<p>至於效能基本上也不至於太差，對一個一般的網站來說，Heroku的1個dyno(Heroku的計價單位)差不多是可以處理10~50 request/second。如果覺得不夠用，也可以考慮它的<a href="http://www.heroku.com/pricing">付費方案</a>來增加dyno數：</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-price.png" alt="image" /></p>

<p>只要拉一下選項，調整dyno數，就可以知道每個月要花多少費用了。</p>

<h1>申請</h1>

<p>請到<a href="https://api.heroku.com/signup">這裡</a>填寫Email，不需要額外的費用。</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-signup.png" alt="image" /></p>

<p>填寫完成後應該不久就會收到一封啟用的認證信，點擊認證連結回到Heroku網站，設定登入密碼：</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-password.png" alt="image" /></p>

<p>這樣就完成申請的程序了。</p>

<h1>安裝</h1>

<p>有兩個工具是使用Heroku會用得上的：Ruby以及Git。Ruby使用1.8或1.9版本皆可，個人建議使用1.9.2的版本，如果你不想在電腦裡裝太多版本的Ruby的話，也可參考<a href="http://www.openfoundry.org/tw/tech-column/8513-rvm-ruby-environment-version-manager">這篇</a>，使用RVM來安裝Ruby。</p>

<p>以下範例因為都是在RVM執行的，所以不會需要root權限，如果你用的是一般系統的Ruby的話，可能會需要<code>sudo</code>來取得root權限才能順利安裝。</p>

<p>裝好Git跟Ruby之後，Heroku有打包好的gem可以使用：</p>

<pre><code>&gt; gem install heroku
Fetching: rubyzip-0.9.5.gem (100%)
Fetching: heroku-2.15.3.gem (100%)
Successfully installed rubyzip-0.9.5
Successfully installed heroku-2.15.3
2 gems installed
</code></pre>

<h1>建立專案</h1>

<p>裝好Heroku之後，我們使用<code>heroku create</code>指令來建立一個空的專案：</p>

<pre><code>&gt; heroku create
Enter your Heroku credentials.
Email: eddie@eddie.com.tw
Password:
Could not find an existing public key.
Would you like to generate one? [Yn] n
Creating deep-spring-4010... done, stack is bamboo-mri-1.9.2
http://deep-spring-4010.heroku.com/ | git@heroku.com:deep-spring-4010
</code></pre>

<p>Heroku會在第一次建立專案的時候問你剛才申請的帳號密碼，如果你不想這麼麻煩，在上面的過程中它也會問你要不要建立一組public key，如果選擇<code>Y</code>就會引導你建立一組public key。</p>

<p>在一開始創建專案的時候，Heroku會自動幫你隨機產生一個名字，以上面的範例來看就是<code>deep-spring-4010</code>。再來我們打開瀏覽器，連上<code>http://deep-spring-4010.heroku.com/</code>，應該可以看到這個畫面：</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-init.png" alt="image" /></p>

<p>如果上面這個<code>deep-spring-4010</code>的名字你不喜歡，也可以到Heroku網站後台去修改，或是直接在一開始建立的時候就指定名稱：</p>

<pre><code>&gt; heroku create hello_kitty
</code></pre>

<p>這樣就會幫你用<code>hello_kitty</code>這個名稱來建立專案，只要名稱沒有先被申請走，你就可以使用。Heroku還有提供更多其它方便的指令可以使用，詳細內容可參考Heroku的<a href="http://devcenter.heroku.com/categories/command-line">這篇說明</a>。</p>

<h1>上傳你的應用程式</h1>

<p>不像一般的網站空間是透過FTP上傳檔案，Heroku是透過Git來發佈的。不過在這之前，我們先來簡單的用Rails的scaffold來快速的建立一個簡單的小程式，待會我們要把這個簡單的程式上傳到Heroku上。</p>

<h2>建立Rails專案</h2>

<pre><code>&gt; rails new my_heroku_demo
.. 訊息略 ..

&gt; cd my_heroku_demo
.. 訊息略 ..

&gt; rails g scaffold Book title:string author:string publish_date:date

&gt; rake db:migrate
==  CreateBooks: migrating ===================
-- create_table(:books)
        -&gt; 0.0019s
==  CreateBooks: migrated (0.0023s) ==========

&gt; rails s
.. 訊息略 ..
</code></pre>

<p>打開瀏覽器連上<code>http://127.0.0.1:3000/books</code>應該就能看到剛剛建立的頁面。</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-scaffold.png" alt="image" /></p>

<p>如果各位對Ruby on Rails不熟悉的話，建議可以參考一下Rails官網上的這篇文章<a href="http://guides.rubyonrails.org/getting_started.html">Getting Started with Rails</a>。</p>

<h2>部署</h2>

<p>網站做好後，接下來就是要把東西上傳到Heroku上。請在剛剛建立的專案底下輸入指令：</p>

<pre><code>&gt; git init .
Initialized empty Git repository in /tmp/my_heroku_demo/.git/

&gt; git add .

&gt; git commit -m 'first commit'
.. 訊息略 ..
</code></pre>

<p>再來要把遠端的Heroku加進來：</p>

<pre><code>&gt; git remote add heroku git@heroku.com:deep-spring-4010.git
</code></pre>

<p>最後再一個<code>git push</code>指令，就可以把做好的東西&#8221;推&#8221;上Heroku：</p>

<pre><code>&gt; git push heroku master
</code></pre>

<p>接下來你應該會看到一些訊息，並且在Heroku上自動幫你安裝一些需要的gem。再來，因為我們有用到資料庫，所以也需要做一下<code>rake db:migrate</code>，不過跟在本機做的時候稍有不同：</p>

<pre><code>&gt; heroku rake db:migrate
</code></pre>

<p>這樣就會對Heroku上的資料庫做migration的動作了。完成之後，請打開瀏覽器輸入網址<code>http://deep-spring-4010.heroku.com/</code>，或是輸入<code>heroku open</code>，也會幫你打開預設的瀏覽器。</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-rails-init.png" alt="image" /></p>

<p>如果看到Rails預設的首頁的話，表示應用程式已經順便傳上去了。再來輸入網址<code>http://deep-spring-4010.heroku.com/books</code>，順利的話，你應該就可以看到剛剛寫好的程式了。</p>

<p>到這裡你大概就已經學會如何Heroku佈署你的Rails應用程式了。在Rails 3.1之前的版本應該都會滿順利的，但如果你用的是Rails 3.1的話(包括之後的版本)，你可能不會這麼順利.. 讓我們繼續看下去。</p>

<h1>問題</h1>

<p>雖然Heroku很方便，但有個比較大的問題是Heroku是個&#8221;唯讀&#8221;的平台，所以如果你想類似檔案上傳或相簿功能的網站的話，上傳的東西需要另外想辦法傳到別的地方(例如上傳到Amazon的S3)。而在Rails 3.1之後引進了<code>asset pipeline</code>，靜態檔案會動態產生，而Heroku沒辦法讓你這樣做，所以，你需要先在本機先把asset編譯好之後再推一次上去：</p>

<pre><code>&gt; rake assets:precompile RAILS_ENV=productioran
.. 訊息略 ..

&gt; git add .

&gt; git commit -m 'add precompied assets'
.. 訊息略 ..

&gt; git push heroku
.. 訊息略 ..
</code></pre>

<p>另外，如果你在做<code>heroku rake db:migrate</code>這個步驟的時候出現這個錯誤訊息的話：</p>

<pre><code>&gt; heroku rake db:migrate
rake aborted!
Please install the postgresql adapter: `gem install activerecord-postgresql-adapter` (pg is not part of the bundle. Add it to Gemfile.)

Tasks: TOP =&gt; db:migrate =&gt; db:load_config
(See full trace by running task with --trace)
</code></pre>

<p>請打開你的Gemfile，加上這一段：</p>

<pre><code>group :production do
    gem "pg"
end
</code></pre>

<p>加完之後再執行：</p>

<pre><code>&gt; bundle install --without production
</code></pre>

<p>應該就可以正常運作了。</p>

<h1>Heroku的後台管理</h1>

<p>我們回到Heroku網站，登入之後可以看到目前有建立哪些app：</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-applist.png" alt="image" /></p>

<p>例如我們看看我們剛剛建立的那個<code>deep-spring-4010</code>：</p>

<p><img src="http://blog.eddie.com.tw/images/2012/heroku-app.png" alt="images" /></p>

<p>可以看到關於這個app的使用情況。如果這個專案不要了，也可以直接從後台刪除掉。</p>

<h1>結論</h1>

<p>Heroku提供了一個可以簡單、快速佈署Ruby應用程式的平台，不用自己維護主機，不需要的時候隨時可以停掉服務，或是萬一臨時要加大硬體需求或頻寬，只要線上刷卡就可以輕鬆解決，設定上相當簡單。</p>

<p>不過就以就費用來看的話，加大dyno數來應付更大需求是很方便，但它可能不會是最便宜的方案(甚至其實還滿貴的)。我個人覺得它很適合試一些簡單的小專案，或是一些臨時想到的idea，用Rails快速的idea做出來，再丟上Heroku的免費額度試一下大家的反應如何，如果真的越做越大的話，也許再考慮正式投資更多的預算或硬體。</p>

<p>畢竟開發專案，最重要的就是先把東西做出來，之後要做更大規模的，現在的雲端平台的延展性(Scalability)都還不錯，通常只要花錢就可以幾乎無痛昇級。</p>

<p>不久前Heroku還提供了對Facebook app的支援，對想要在Facebook上建立應用程式的人來說也是一大福音，連Ruby的發明者松本行弘也在不久前加入了Heroku，受聘為首席架構師，相信Heroku能提供的服務會越來越豐富。如果各位有在寫Ruby應用程式卻還苦於找不到地方放的話，建議不妨可以試試看Heroku。</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2012/01/06/heroku-the-best-cloud-platform-on-ruby-language/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[我的工具箱]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/5S0H5eb-8zM/" />
    <updated>2012-01-04T13:51:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2012/01/04/my-toolbox</id>
    <content type="html"><![CDATA[<p>先說明一下，我目前主要的作業系統是Mac OS，工作主要是網站程式開發，前端是Flash、ActionScript以及JavaScript，後端則是Ruby以及Ruby on Rails，應該再過半年左右就會加入Mac app/iOS app的專案。以下來獻曝一下我目前比較常用的工具箱，供大家參考。</p>

<h1>軟體外掛</h1>

<h2>主力的右手</h2>

<table>
<thead>
<tr>
<th> 工具                    </th>
<th> 價錢          </th>
<th> 說明</th>
</tr>
</thead>
<tbody>
<tr>
<td> MacVim                </td>
<td> Free        </td>
<td> 最近換上手的文字編輯器，用它之後把不少工具都暫時放到第二線去了，選用它原因可參考<a href="http://blog.eddie.com.tw/2011/12/26/vim/">這篇</a>。</td>
</tr>
<tr>
<td> <s>TextMate</s>       </td>
<td> $59         </td>
<td> 寫Ruby/Rails的強力好工具，但中文字型一直是很大的問題，我換了新歡之後，目前已暫居第二線。<br />網址：<a href="http://macromates.com/">http://macromates.com/</a></td>
</tr>
<tr>
<td> <s>Sublime Text 2</s> </td>
<td> Free or $59 </td>
<td> 也是很棒的文字編輯器，中文字顯示正常。目前也因為MacVim的關係，暫時把它移到二軍了。<br />網址：<a href="http://www.sublimetext.com/2">http://www.sublimetext.com/2</a></td>
</tr>
<tr>
<td> <s>Mou</s>            </td>
<td> Free        </td>
<td> 我覺得是目前看到最好用的Markdown編輯器(同上，目前暫居二軍)。<br />網址：<a href="http://mouapp.com/">http://mouapp.com/</a></td>
</tr>
<tr>
<td> <s>ByWord</s>         </td>
<td> $9.99       </td>
<td> 也是好用的Markdown編輯器(同上，目前暫居二軍)。<br/>網址：<a href="http://bywordapp.com/">http://bywordapp.com/</a></td>
</tr>
<tr>
<td> Xcode                 </td>
<td> Free        </td>
<td> 寫Mac app/iOS app用的。<br />網址：<a href="http://developer.apple.com/xcode/">http://developer.apple.com/xcode/</a></td>
</tr>
<tr>
<td> iTerm2                </td>
<td> Free        </td>
<td> Mac OS內建的Terminal替代品。<br />網址：<a href="http://www.iterm2.com/#/section/home">http://www.iterm2.com/#/section/home</a></td>
</tr>
<tr>
<td> Sequel Pro            </td>
<td> Free        </td>
<td> 圖形介面的MySQL Client。<br />網址：<a href="http://www.sequelpro.com/">http://www.sequelpro.com/</a></td>
</tr>
<tr>
<td> Balsamiq Mockups      </td>
<td> $79         </td>
<td> 用來畫網站layout的好工具，有點貴就是了。<br />網址：<a href="http://www.balsamiq.com/products/mockups">http://www.balsamiq.com/products/mockups</a></td>
</tr>
<tr>
<td> Adobe工具組              </td>
<td> 價錢請見官網      </td>
<td> 很貴，不過是吃飯的傢伙，沒辦法..</td>
</tr>
</tbody>
</table>


<br />


<h2>輔助的左手</h2>

<table>
<thead>
<tr>
<th> 工具             </th>
<th> 價錢           </th>
<th> 說明</th>
</tr>
</thead>
<tbody>
<tr>
<td> TotalFinder    </td>
<td> $18          </td>
<td> Mac OS內建的Finder的替代品。<br />網址 <a href="http://totalfinder.binaryage.com/">http://totalfinder.binaryage.com/</a></td>
</tr>
<tr>
<td> Alfred         </td>
<td> Free, or £15 </td>
<td> Mac OS內建的Spotlight的替代品，有了它之後，原本得在dock排排站的軟體都可以省掉了，只要透過簡單的關鍵字就可以直接叫出來，相當方便!(而且我覺得比QuickSilver還好用)<br />網址：<a href="http://www.alfredapp.com/">http://www.alfredapp.com/</a></td>
</tr>
<tr>
<td> TextExpander   </td>
<td> $34.95       </td>
<td> 可以快速的，而且是System-wide的，有這個的話，即使你用的編輯器沒有支援你習慣的code snippet也沒問題了。snippet<br />網址：<a href="http://www.smilesoftware.com/TextExpander/">http://www.smilesoftware.com/TextExpander/</a></td>
</tr>
<tr>
<td> Divvy          </td>
<td> Free, or $14 </td>
<td> 用來調整視窗大小的小工具。<br />網址：<a href="http://mizage.com/#macdivvy">http://mizage.com/#macdivvy</a></td>
</tr>
<tr>
<td> ScreenFlow     </td>
<td> $99          </td>
<td> 我用來錄畫面的工具。<br />網址：<a href="http://www.telestream.net/screen-flow/overview.htm">http://www.telestream.net/screen-flow/overview.htm</a></td>
</tr>
<tr>
<td> KeyCastr       </td>
<td> Free         </td>
<td> 可以在螢幕上顯示目前按了什麼按鍵，通常會拿來跟ScreenFlow一起服用。<br />網址：<a href="http://stephendeken.net/software/keycastr">http://stephendeken.net/software/keycastr</a></td>
</tr>
<tr>
<td> ColorTagGen    </td>
<td> Free         </td>
<td> 吸顏色用的好用小工具。<br />網址：<a href="http://itunes.com/mac/colortaggen">http://itunes.com/mac/colortaggen</a></td>
</tr>
<tr>
<td> RemoteBuddy    </td>
<td> £19.99       </td>
<td> 可以把Wii手把當做簡報器用的工具。<br />網址：<a href="http://www.iospirit.com/products/remotebuddy/">http://www.iospirit.com/products/remotebuddy/</a></td>
</tr>
<tr>
<td> Cyberduck      </td>
<td> Free         </td>
<td> 傳檔工具，支援FTP/SCP，也支援AWS的S3。<br />網址：<a href="http://cyberduck.ch/">http://cyberduck.ch/</a></td>
</tr>
<tr>
<td> Welly          </td>
<td> Free         </td>
<td> 用來連上BBS的。<br />網址：<a href="http://code.google.com/p/welly/">http://code.google.com/p/welly/</a></td>
</tr>
<tr>
<td> SourceTree     </td>
<td> Free         </td>
<td> Mac OS上少數免費而且還不錯用的圖形化版本管理工具。<br />網址：<a href="http://www.sourcetreeapp.com/">http://www.sourcetreeapp.com/</a></td>
</tr>
<tr>
<td> Github.app     </td>
<td> Free         </td>
<td> Github出的小工具。<br />網址：<a href="http://mac.github.com/">http://mac.github.com/</a></td>
</tr>
<tr>
<td> Gmail Notifier </td>
<td> Free         </td>
<td> 會在系統列通知信件的小工具<br />網址：<a href="http://toolbar.google.com/gmail-helper/notifier_mac.html">http://toolbar.google.com/gmail-helper/notifier_mac.html</a></td>
</tr>
<tr>
<td> Dropbox        </td>
<td> Free         </td>
<td> 應該不用太多介紹了，我大多是拿來跟外發或客戶交換檔案用的。<br />網址：<a href="https://www.dropbox.com/">https://www.dropbox.com/</a></td>
</tr>
<tr>
<td> Adium          </td>
<td> Free         </td>
<td> Microsoft是有給Mac出了一款MSN Client，但沒辦法收離線訊息!! 還好這隻小鴨子功能也不差，支援離線訊息之外，還支援好幾家的協定(Gtalk、Facebook、ICQ等)，就是傳檔的時候慢了點，還有偶爾會當機這樣的問題而已。<br />網址：<a href="http://adium.im/">http://adium.im/</a></td>
</tr>
<tr>
<td> Twitter        </td>
<td> Free         </td>
<td> Twitter官方的app，可在Mac App Store取得。<br />網址：<a href="http://itunes.apple.com/us/app/twitter/id409789998">http://itunes.apple.com/us/app/twitter/id409789998</a></td>
</tr>
</tbody>
</table>


<br />


<h2>專案管理</h2>

<table>
<thead>
<tr>
<th> 工具      </th>
<th> 價錢     </th>
<th> 說明</th>
</tr>
</thead>
<tbody>
<tr>
<td> Redmine </td>
<td> Free   </td>
<td> 好用的專案管理工具，我都是拿來給客戶用的，有什麼問題就請客戶在這個地方開票，比Email往來更有效率，也更好管理。<br />網址：<a href="http://www.redmine.org/">http://www.redmine.org/</a></td>
</tr>
</tbody>
</table>


<h2>Chrome Plugins</h2>

<table>
<thead>
<tr>
<th> 工具                          </th>
<th> 說明</th>
</tr>
</thead>
<tbody>
<tr>
<td> Send to Kindle              </td>
<td> 用來把看不完的頁面丟往Kindle再慢慢啃的好工具</td>
</tr>
<tr>
<td> Awesome Screenshot          </td>
<td> 方便的瀏覽器拍圖外掛</td>
</tr>
<tr>
<td> Color Pick                  </td>
<td> 吸顏色用的，但僅限於網頁頁面。</td>
</tr>
<tr>
<td> Evernote                    </td>
<td> 看名字就知道是來用跟Evernote同步的。</td>
</tr>
<tr>
<td> goo.gl URL Shortener        </td>
<td> 縮網址用的。</td>
</tr>
<tr>
<td> Library Detector            </td>
<td> 可以偵測這個頁面有用了哪些JavaScript Library。</td>
</tr>
<tr>
<td> LiveReload                  </td>
<td> 用來跟LiveReload串接的外掛</td>
</tr>
<tr>
<td> LocalStorage Monitor        </td>
<td> 可以檢視目前這個頁面的Local Storage狀況。</td>
</tr>
<tr>
<td> 新同文堂                        </td>
<td> 簡繁轉換的工具</td>
</tr>
<tr>
<td> Orbvious Interest           </td>
<td> 可以把目前這個沒時間看或來不及看完的頁面往Read it Later送，可以稍後再讀。</td>
</tr>
<tr>
<td> Pretty Beautiful Javascript </td>
<td> 把JavaScript美化的小工具</td>
</tr>
<tr>
<td> Try coffeeScript            </td>
<td> 直接在瀏覽器裡就可以寫CofeeScript，看看效果如何。</td>
</tr>
<tr>
<td> Vimium                      </td>
<td> 用Vim的操作方法來操作瀏覽器，跟Vim一樣，習慣之後真的會上癮。</td>
</tr>
</tbody>
</table>


<p>以上工具皆可在Chrome Web Store找得到</p>

<h2>其它</h2>

<table>
<thead>
<tr>
<th> 工具     </th>
<th> 價錢     </th>
<th> 說明</th>
</tr>
</thead>
<tbody>
<tr>
<td> iTunes </td>
<td> Free   </td>
<td> 這是個很重要的東西，平常除了聽音樂之外，我還訂了許多的screencast、podcast，還有Stanford超紮實的線上課程，這些都是很棒的資訊來源。</td>
</tr>
</tbody>
</table>


<br />


<h1>實體外掛</h1>

<p>除了軟體的工具、外掛之外，還有些實體的外掛..</p>

<h2>Kindle</h2>

<p>看書用的好東西，細節可參考<a href="http://blog.eddie.com.tw/2011/12/10/kindle/">這篇</a></p>

<h2>iPad</h2>

<p>最近都被老媽跟小朋友霸佔走了，就不多提了.. Orz</p>

<h2>機械鍵盤</h2>

<p>我的工作有很大時間都是在敲鍵盤，所以投資給自己打起來比較舒服(增加爽度)的鍵盤是剛好而已，Mac內建的巧克力鍵盤是不錯打，但就是少了手指頭的回饋。</p>

<p><img src="http://blog.eddie.com.tw/images/2012/filco-keyboard.jpg" alt="image" /></p>

<h2>外接螢幕</h2>

<p>我目前工作用的主要是laptop，螢幕不大，沒有第二顆外接螢幕在開發網站的時候相當痛苦，真的一但習慣之後就回不去了。</p>

<h2>椅子</h2>

<p>跟鍵盤一樣，我幾乎是整天都是坐著的，所以投資給自己一隻坐起來比較舒服的椅子也是剛好而已。</p>

<h2>便利貼</h2>

<p>這是最近加入的習慣，我用實體的便利貼做為輔助的工具。雖然說電腦類的便利貼軟體那麼多可以選擇，但我還是覺得比不上手寫 &amp; 貼在螢幕上來得直覺：</p>

<p><img src="http://blog.eddie.com.tw/images/2012/stickers-on-laptop.jpg" alt="image" /></p>

<p>所以整個組合起來，看起來大概會是這樣：</p>

<p><img src="http://blog.eddie.com.tw/images/2012/my-working-space.jpg" alt="image" /></p>

<p>(抱歉不是很整齊..)</p>

<p>至於Windows上的工具組合，我已經忘得差不多了，Windows目前只有拿來測試IE瀏覽器以及網路ATM轉帳用途而已..以上，如果大家也有好用的工具，也歡迎一起留言討論。</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2012/01/04/my-toolbox/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[哈囉，2012!]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/0l0hfLmqj_g/" />
    <updated>2011-12-30T09:09:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/30/hello-2012</id>
    <content type="html"><![CDATA[<p>對於新的東西，寫程式的總是不免俗的要來個&#8221;Hello World&#8221;!</p>

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

<ul>
<li>認識了更多的神人/高手，雖然很多目前都還看不到車尾燈，但至少有個方向可以跟</li>
<li>辦了9場的<a href="https://www.facebook.com/thestudygroup">Flash/ActionScript讀書會</a>，每回人數在50~100之間，感謝大家的支持</li>
<li>跟<a href="http://dd.deep.tw/">@pct</a>一起辦了第一屆的<a href="http://phpconf.tw/2011">PHPConf in Taiwan</a></li>
<li><a href="http://blog.eddie.com.tw/presentations/">有14場公開的表演</a>，其中有的是教育訓練，有的是心得分享，真是愛現!</li>
<li>Blog竟然有90篇文章!! 我剛自己算了一下也嚇到</li>
</ul>


<h2>希望更熟悉技能</h2>

<ul>
<li>Vim(希望可以練到跟吃飯、呼吸一樣自然就好)</li>
<li>Ruby/Rails(往Best Practice前進)</li>
<li>JavaScript</li>
<li>Cocoa Framework</li>
</ul>


<h2>許願</h2>

<ul>
<li>小朋友(們)可以順利長大</li>
<li>希望可以做出自己的產品</li>
<li>繼續把Flash/ActionScript讀書會辦下去</li>
<li>希望可以投稿國外某些知名網站(練英文的時候到了)</li>
<li>希望COSCUP/OSDC/RubyConf Taiwan/RubyKaigi/PHPConf Taiwan這5個研討會，至少有2/5可以上台講，而不是只是坐在底下當聽眾</li>
<li>希望可以像閃光哥一樣，也可以有一本書(我要遺臭萬年用的)</li>
<li>希望體重可以再比現在再少個5公斤</li>
<li>公司生意.. 順利就好</li>
</ul>


<p>許完願了，但光許願是不會實現的，所以我要開始動手寫書的TOC了!</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/30/hello-2012/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Vim的操作小技巧]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/VslvsQjfUyI/" />
    <updated>2011-12-28T12:00:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/28/vim-tips</id>
    <content type="html"><![CDATA[<p>Vim的操作除了基本的<code>hjkl</code>之外，快速鍵組合相當多，不過大概有個規則。以下是我自己個人比較常會用到，而且覺得還滿方便的操作小技巧，寫起來幫自己加深記憶，希望也對有需要的朋友有幫助。</p>

<h2>說明</h2>

<ol>
<li><code>ENTER</code> = 按下enter鍵，<code>CTRL</code> = 按下ctrl鍵，<code>ALT</code> = 按下alt鍵，如果是大寫字母例如<code>G</code> = shift + g，<code>CTRL w j</code> = 按著ctrl鍵不放，再按下w，再按下j</li>
<li>這裡提到的都是Vim或是plugin內建的指令，如果你不喜歡或覺得難按，可以透過修改<code>.vimrc</code>來改變快速鍵的對映</li>
<li>以下指令都是在一般模式(Normal Mode)下使用</li>
</ol>


<h2>游標移動</h2>

<ul>
<li><code>gg</code> = 移到整份文件的最上方</li>
<li><code>G</code> = 移到整份文件的最下方</li>
<li><code>H</code> = 移到目前螢幕的最上方</li>
<li><code>L</code> = 移到目前螢幕的最下方</li>
<li><code>10 ENTER</code> = 游標往下移動10行，前面的數字表示行數</li>
<li><code>:10 ENTER</code> = 游標直接移動到第10行</li>
<li><code>{</code>、<code>}</code> = 把游標移動到上一個、下一個段落</li>
<li><code>CTRL w j</code> = 把游標往下面的分割視窗移動</li>
<li><code>CTRL w k</code> = 把游標往上面的分割視窗移動</li>
<li><code>CTRL w h</code> = 把游標往左邊的分割視窗移動</li>
<li><code>CTRL w w</code> = 在各個分割視窗間切換</li>
</ul>


<p>建議可以搭配<a href="http://www.vim.org/scripts/script.php?script_id=3526"> EasyMotion </a>更有效率的移動游標</p>

<h2>搜尋</h2>

<ul>
<li><code>/</code> = 搜尋</li>
<li><code>*</code> = 移往下一個搜尋結果</li>
<li><code>#</code> = 移往上一個搜尋結果</li>
</ul>


<h2>編輯</h2>

<ul>
<li><code>u</code> = undo，回到上一步</li>
<li><code>CTRL r</code> = redo，回復undo</li>
<li><code>.</code> = 重複上一個步驟</li>
<li><code>~</code> = 改變英文字母的大小寫，本來大寫會變小寫，小寫會變大寫</li>
<li><code>:m+</code> = 把目前這一行往下移動一行</li>
<li><code>:m-2</code> = 把目前這一行往上移動一行</li>
<li><code>&gt;&gt;</code>、<code>&lt;&lt;</code> = 增加、減少縮排</li>
<li><code>yy</code>或<code>Y</code> = 複製游標所在的這一整行</li>
<li><code>p</code>、<code>P</code> = 在游標之後、之前貼上複製的內容</li>
<li><code>"ayy</code> = 跟<code>yy</code>有點像，但是是把複製的東西放到<code>a 暫存器</code>裡，這個<code>a</code>可以用其它25個英文字母代替，可以用<code>:reg</code>指令把目前的暫存器叫出來看</li>
<li><code>"ap</code> = 在游標之後貼上<code>a 暫存器</code>裡的內容</li>
</ul>


<h2>模式切換</h2>

<ul>
<li><code>ESC</code> 或 <code>CTRL [</code> = 回到命令模式，ESC是獨立一顆比較好按，但比較遠，如果你不想讓你的手離開打字區的話，可以選用<code>CTRL [</code>，或是在<code>~/.vimrc</code>裡自訂快速鍵</li>
<li><code>CTRL v</code> = visual block模式，可進行像TextMate按住alt鍵的區塊選取</li>
</ul>


<h2>NERDTree</h2>

<ul>
<li><code>B</code> = 叫出bookmark</li>
<li><code>C</code> = 把目前游標停留的這個目錄設定為根目錄</li>
<li><code>p</code> = 把游標移動到上一層目錄</li>
<li><code>P</code> = 把游標移動到根目錄</li>
<li><code>J</code> = 把游標移往這個結點的第一個</li>
<li><code>K</code> = 把游標移往這個結點的最後一個</li>
<li><code>u</code> = 把樹狀結構的根目錄往上移一層</li>
<li><code>I</code> = 切換是否顯示隱藏檔案</li>
<li><code>m</code> = 叫出NERDTree的系統選單</li>
</ul>


<h2>其它</h2>

<ul>
<li><code>:!</code> = 執行外部指令，例如<code>:!ls</code>則是執行<code>ls</code>指令</li>
</ul>


<h2>參考資料</h2>

<p>這裡有幾篇我覺得寫得很棒的文章，可以更清楚的知道在Vim裡操作的原理</p>

<ul>
<li><a href="http://blog.carbonfive.com/2011/10/17/vim-text-objects-the-definitive-guide/">Vim Text Objects: The Definitive Guide</a></li>
<li><a href="http://yanpritzker.com/2011/12/16/learn-to-speak-vim-verbs-nouns-and-modifiers/">Learn to speak vim – verbs, nouns, and modifiers!</a></li>
<li><a href="http://www.study-area.org/tips/vim/index.html">大家來學Vim</a>，雖然是將近10年前的文件，但很多還是適用</li>
</ul>


<p>Vim的快速鍵組合如果用得熟的話，整個編輯的過程中是幾乎可以不動到滑鼠的，不過還是要多練習啦，差不多練到跟吃飯睡覺一樣熟練就可以了。打完收工 :wq</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/28/vim-tips/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Vim]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/Sa65oLuH_pk/" />
    <updated>2011-12-26T19:58:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/26/vim</id>
    <content type="html"><![CDATA[<h2>前言</h2>

<p>在十年前開始接觸FreeBSD的時候，就聽聞過Vi/Vim這東西，那時候第一眼的感覺是：「這東西看起來好陽春，功能一定也很陽春」。當時在終端機上也還有別的編輯器可以選擇，例如Joe、Nano等，而且在本機的作業系統(Windows)也有其它的選擇，例如UltraEdit。</p>

<p>以前會覺得寫程式、開發軟體，沒有IDE一定沒辦法。有些程式、軟體的確是需要IDE的幫忙，不然不知道怎麼寫。直到近幾年的工作幾乎用的都是文字編輯器，才發現其實文字編輯器可以做的事情相當多。二年多前開始把作業系統換成Mac OS之後，除了要寫Flash需要開Flash IDE + Flash Builder之外，其它幾乎就是只用<a href="http://macromates.com/">TextMate</a>了。雖然說它的中文顯示問題一直被大家嫌到不行，而且傳說中的2.0版也一直沒消息，但它依舊是我開發上的首選工具。</p>

<p>TextMate 2實在是讓人等太久了，所以大家開始找它的替代品。不久前發現<a href="http://www.sublimetext.com/2">Sublime Text 2</a>這個編輯器，它的中文字是正常的，外掛看起來也滿夠用的，而且還可以吃TextMate的bundle跟theme，本來打算換過去的時候突然出現TextMate 2的消息了，聽說中文顯示是正常的。但這時候我卻想，我還要過著這種逐水草而居的生活到什麼時候? 難道沒有一款編輯器是可以學了之後就一直用的嗎?</p>

<p>這時候我想到不久前才剛過20歲生日的Vi/Vim。雖然不久前陣子有練了一下手感，但沒認真下定決心要把它當成是自己吃飯的工具。於是，就找了個週末來認真的練了一下手感，發現出乎我意料的好用，之前在TextMate/Sublime Text 2上可以做的功能，在Vim幾乎都有替代品，我以前真的是錯怪它了!</p>

<p>以下大概是我目前有用到的外掛跟設定，不是很多，但就我自己工作上用得到的。這是我目前的樣子(其實NERDTree比我想像中的漂亮)
<img src="http://blog.eddie.com.tw/images/2011/vim-screen.png" alt="image" /></p>

<h2>外掛與設定</h2>

<p><a href="https://github.com/kaochenlong/eddie-vim/blob/master/.vimrc" target="_blank">我的.vimrc設定</a></p>

<p class="info">我把自己的設定檔跟用到的外掛放了一份在<a href="https://github.com/kaochenlong/eddie-vim" target="_blank">這裡</a>，有興趣的朋友可以參考看看 :)</p>


<h3>我用到的外掛：</h3>

<h4><a href="https://github.com/tpope/vim-pathogen">Pathogen</a></h4>

<p>用來管理外掛的外掛。以前安裝外掛，常常得把一包程式裡的各個資料夾到處撒在<code>~/.vim</code>資料夾裡，現在透過pathogen的話只要放在<code>~/.vim/bundle</code>裡就差不多行了，相當方便。</p>

<h4><a href="https://github.com/scrooloose/nerdtree">NerdTree</a> &amp;&amp; <a href="https://github.com/jistr/vim-nerdtree-tabs">NerdTreeTab</a></h4>

<p>Vim的檔案總管啦，當資料夾一多，沒有它不知道該怎麼工作了。</p>

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


<p>我在.vimrc裡有把NERDTreeToggle設定到F2鍵上，這樣就可以快速的打開、關閉了。</p>

<h4><a href="https://github.com/scrooloose/nerdcommenter">NerdCommenter</a></h4>

<p>用這個可以方便的幫程式碼來做註解</p>

<h4><a href="https://github.com/msanders/snipmate.vim">SnipMate</a></h4>

<p>看名字就知道它是從TextMate借過來的，如果覺得有不足的也可以自己建。</p>

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


<h4><a href="https://github.com/wincent/Command-T">Command-T</a></h4>

<p>TextMate跟Sublime Text 2都有可以快速搜尋檔案的功能，這個則是補足了Vim這方面的功能，也是我決定把Vim當做主要工具的原因之一。</p>

<h4><a href="https://github.com/tpope/vim-surround">Surround</a></h4>

<p>可以很快的處理單引號、雙引號以及一些html常用的tag的問題，熟練的話會很方便。</p>

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


<h4><a href="https://github.com/tpope/vim-repeat">Repeat</a></h4>

<p>Vim內建的repeat功能在遇到某些事件的時候似乎會失效，加上這個外掛就沒問題了。</p>

<h4><a href="https://github.com/Lokaltog/vim-easymotion">EasyMotion</a></h4>

<p>可以在不需要滑鼠的幫助下，快速的切換游標的位置。</p>

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


<h4>幾個自己有在用的syntax highlight以及配色</h4>

<ul>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1061">actionscript</a></li>
<li><a href="https://github.com/kchmck/vim-coffee-script">coffeescript</a></li>
<li><a href="https://github.com/plasticboy/vim-markdown/">markdown</a></li>
<li><a href="https://github.com/vim-ruby/vim-ruby">ruby</a></li>
<li><a href="https://github.com/tpope/vim-rails">rails</a></li>
</ul>


<p>發現我幾乎整篇都是偷懶的直接貼別人的影片啊 Orz 另外如果你本來在TextMate下有喜歡的配色，也可以透過<a href="http://coloration.sickill.net/">這個工具</a>來轉成給Vim的格式。</p>

<p><span class="warning">有些外掛的更新後續都是在github上，要用的時候請注意最後更新日期。</span></p>

<br />


<h2>其它工具</h2>

<h3><a href="http://www.alfredapp.com/" target="_blank">Alfred</a></h3>

<p>付費軟體。有這個工具的幫忙，原本螢幕下方放滿的工具就可以少放很多了，要開軟體也不需要用滑鼠去點，只要輸入幾個關鍵字就可以跳出來：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/tool-alfred.png" alt="image" /></p>

<h3><a href="https://chrome.google.com/webstore/detail/dbepggeogbaibhgnhhndojpepiihcmeb" target="_blank">Vimium</a></h3>

<p>讓瀏覽器也用Vim的操作方式來瀏覽(Chrome限定)</p>

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


<h3><a href="http://vimperator.org/vimperator" target="_blank">Vimperator</a></h3>

<p>Firefox也有類似功能的外掛可以用，感謝<a href="http://laoyang945.github.com/" target="_blank">老杨</a>提供。</p>

<h2>結論</h2>

<p>自己順手的兵器，其實應該只要一把就夠了。雖然我用的是MacVim，但會儘量避免用太多Mac專屬的設定，這樣一來我在本機的作業環境(Mac OS、Windows、Ubuntu)在切換的時候都可以有差不多的編輯習慣，甚至連遠端終端機作業的時候也不會差很多。</p>

<p>Vim很強大，但它不是一個可以一、兩天就能上手的工具。我相信只要學得好，它絕對是可以到哪裡都走透透的兵器。現在還不夠熟，不過我相信一直強迫自己用下去，遲早可以跟它變好朋友。(像這篇文章就是在Vim底下打的，打得很不順，但就強迫自己練習)。接下來應該就是繼續把它再磨利一點，再練得順手一些，讓自己可以更快的完成工作，有更多時間可以做自己想做的事，以及陪家人(講是這樣講.. 但大概會花更多時間再寫更多的程式碼吧)</p>

<p>各位如果有不錯的外掛也歡迎留言一起討論囉 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/26/vim/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[Automated Testing in Javascript]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/flci88n_DuQ/" />
    <updated>2011-12-22T05:30:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/22/automated-testing-in-javascript</id>
    <content type="html"><![CDATA[<p>這是在<a href="http://www.jaceju.net/blog/" target="_blank">大澤木小鐵(Jace)</a>主辦的第一回<a href="http://registrano.com/events/webdev-party-01" target="_blank">WebDev Party</a>上用到的投影片：
<a href="http://speakerdeck.com/u/eddie/p/automated-testing-in-javascript" target="_blank"><img src="http://blog.eddie.com.tw/images/2011/speakerdeck-automated-testing-in-javascript.jpg" alt="image" /></a>
<a href="http://speakerdeck.com/u/eddie/p/automated-testing-in-javascript" target="_blank">View on Speak Deck</a> | <a href="http://blog.eddie.com.tw/downloads/files/2011/automated-testing-in-javascript.pdf">Download PDF</a> | <a href="http://blog.eddie.com.tw/downloads/files/2011/automated-test-in-javascript.zip">Download ScreenCast</a></p>

<p>這是當天的錄影：</p>

<iframe src="http://player.vimeo.com/video/34133238?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe>


<p>主要內容是分享一些我近期在做自己的產品的時候用到的一些測試工具組合及心得。原本打算用中文做投影片，但還是無法割捨漂亮的英文字體。這應該是今年的最後一場表演了，希望大家會喜歡。</p>

<h3>有提到的工具：</h3>

<ul>
<li><a href="http://docs.jquery.com/QUnit" target="_blank">QUnit</a> - A easy-to-use JavaScript testing framework.</li>
<li><a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> - A BDD framework for testing your JavaScript code.</li>
<li><a href="http://zombie.labnotes.org/" target="_blank">Zombie.js</a> - A headless testing tool.</li>
<li><a href="http://sinonjs.org/" target="_blank">Sinon.js</a> - Standalone test spies, stubs and mocks for JavaScript.</li>
<li><a href="http://www.phantomjs.org/" target="_blank">Phantom.js</a> - A headless WebKit with JavaScript API.</li>
<li><a href="https://github.com/guard/guard" target="_blank">Guard</a> - A command line tool to easily handle events on file system modifications.</li>
</ul>


<p>若有任何問題或是我講的內容有不對的地方，歡迎大家留言一起討論、指正。之後也會持續的續把一些測試JavaScript的方法跟工具整理成文章，希望可以給大家帶來一點點的幫助。</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/22/automated-testing-in-javascript/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[第九回AS讀書會之測試你的Robotlegs專案]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/ssCwlDIytfc/" />
    <updated>2011-12-14T02:42:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/14/test-your-robotlegs-project</id>
    <content type="html"><![CDATA[<p>這是在第九回的Flash/AS讀書會上用到的投影片：
<a href="http://speakerdeck.com/u/eddie/p/test-your-robotlegs-project" target="_blank"><img src="http://blog.eddie.com.tw/images/2011/speakerdeck-test-in-robotlegs.jpg" alt="image" /></a>
<a href="http://speakerdeck.com/u/eddie/p/test-your-robotlegs-project" target="_blank">View on Speak Deck</a> | <a href="http://blog.eddie.com.tw/downloads/files/2011/test-your-robotlegs-project.pdf">Download PDF</a></p>

<p>部份內容是現場Demo，所以沒辦法在投影片裡看到。在分享的過程，從大家的眼神中似乎可以感覺得出來大家對於&#8221;寫測試&#8221;這件事很陌生(其實我也是新手)，我之後會再花一些時間把關於如何在Flash/ActionScript裡寫測試整理成文章，希望可以讓大家可以更了解TDD(Test-Driven Development)是怎麼一回事，又該怎麼進行。</p>

<p>感謝大家今天天氣這麼冷還能前來參加，咱們下回見 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/14/test-your-robotlegs-project/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[敗家之路之Kindle人生]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/nfTP7fQ_lxs/" />
    <updated>2011-12-10T10:40:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/10/kindle</id>
    <content type="html"><![CDATA[<p class="info">放心，這不是勸敗文也不是開箱文，只是我自己最近用幾天的一點小小心得。</p>


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

<p>我很愛買書、看書，家裡書櫃的書已經多到快裝不下了，但仍樂在其中。每次出門，我包包裡面一定至少會放一本書，不管是等人或是通車的時候都可以拿出來翻。</p>

<p>自從一年前入手ipad後，開始把書裝進去，這樣出門只要帶一台， 如同某購物台業務所說，裡面的書就算有幾百本也不會變重，真的超方便的 XD</p>

<p>不過好景不長，近來我的ipad最近被老媽跟小朋友霸佔了，所以只好再想辦法再弄一台。這回在找替代品有給自己定幾個評估的重點：</p>

<ol>
<li>成本。</li>
<li>是否方便攜帶。</li>
<li>是否支援之前買的電子書。</li>
</ol>


<p>最後評估下來有兩個候選人，一個是Kindle，另一個是Kindle Touch，沒有選其它家的產品是因為他們的功能都太多太複雜了，而且用Kindle在Amazon買書會比較便宜。最後Kindle勝出的原因是它比較便宜，而且Touch的功能我並不需要，我只要可以看書就好。最後感謝在美國的友人的幫忙，幫忙弄了一台79塊美金的Kindle 4。</p>

<h2>使用感想</h2>

<p>入手的第一個感覺是：哇，它好輕喔!</p>

<ul>
<li>電子墨水省電，聽說充一次電可以用很久。</li>
<li>79元版本雖然有廣告，但廣告只會在非閱讀的時候出現，而且老實說廣告看起來還滿漂亮的，不會覺得不舒服或干擾。</li>
<li>在閱讀的時候底下有個進度條，告知目前這本書讀了多少百分比，感覺像打電動會告訴你還有多少經驗值才昇級。</li>
<li>畫面不會發光，所以長時間眼睛看起來不會太辛苦，雖然關燈就看不到了，不過即然都要關燈，表示你也該休息了。</li>
<li>有內建字典功能，雖然是英英字典，但至少比還得另外翻字典要方便多了。</li>
<li>可以畫重點，而且畫的重點可以另外取出來用，還會標記是在哪一本書的第幾頁。</li>
<li>可以與桌上版或iPad版的Kindle閱讀軟體的閱讀進度做sync，也就是說不管在電腦上、iPad上，或是在Kindle上閱讀，都可以同步閱讀進度，另外，除了自己畫的重點之外，也可以看得到別人分享出來的重點，這很棒，有共同筆記的感覺(不過這只有直接在Amazon上買的書才有這個功能，自己上傳的沒有)。</li>
<li>雖然支援PDF格式，但因為畫面只有6吋實在太小，而且Kindle不支援PDF的reflow，也就是說沒辦法像mobi格式一樣的改變字體大小。有些工具可以把PDF轉成mobi格式，但效果不佳，目前看來ePub轉mobi的效果還滿好的。</li>
<li>除了電子書之外，現在有些方便的瀏覽器外掛，可以直接把頁面重新排版成適合Kindle閱讀的內容之後再傳送到Kindle裡，有些很棒的網站來不及看，可以透過這個工具把它存到Kindle裡離線閱讀，這相當好用。個人推薦&#8221;<a href="https://chrome.google.com/webstore/detail/ipkfnchcgalnafehpglfbommidgmalan">Send to Kindle</a>&#8220;(Chrome限定)。</li>
</ul>


<p>我大部份的書都是電腦相關的，遇到有程式碼的時候，我發現其實橫著看就滿舒服的，像這樣：</p>

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

<p>而且這樣我一樣單手就可以很輕鬆的拿著，大拇指可以用來按翻頁鈕，相當沒負擔，這也這也是我當初沒選Touch的原因之一。</p>

<h2>其它週邊</h2>

<p>我知道有些人會比較保護心愛的東西，可能會買皮套或是保護貼之類的。我偶爾也會，但我覺得Kindle並不需要太多的保護措施。因為目前坊間大部份的皮套重量可能就比Kindle本身還重了，當初選擇Kindle的原因之一就是因為它很輕便、好拿，沒道理要再加個皮套來增加重量。螢幕保護貼更是不需要了，因為不是Touch機種，螢幕也不太會弄髒。不過因為Kindle很輕，可能還滿容易不小心手滑飛出去，也許加個果凍套邊框之類的如果不會妨礙翻頁的話還滿ok的。</p>

<p>我不保護它不代表我不愛惜它，而是就像一般的書一樣，書，是買回去讀的，不是買回去擺好看的 :)</p>

<h2>結論</h2>

<p>Kindle對我來說，可能真的是開啟了另一條敗家之路了，重點不在機器本身，而是因為買Kindle版的電子書，不只速度快，而且幾乎都比一般印刷版本還要便宜個幾塊美金，甚至有到對折的。如果買一本書便宜5塊美金的話，買個十幾本那台Kindle的成本就回來了，方便又便宜，真的會讓我之後少跑很多次的天瓏書局了。(或是可能在天瓏看到喜歡的書，然後從Kindle直接下單..orz)</p>

<p>我知道工程師們常會有「拿到新的3C產品不root一下會很不舒服」的症狀，看看能不能hack一下，幫它加功能讓它變得功能更強大或什麼的。我不覺得這樣做有什麼意義，對我來說，當初買Kindle的用途就是拿來看書的，其它的就不要想了。想要多功能的，也許你該考慮是不是用平板電腦就好。Kindle裡面有內建瀏覽器，但我想非必要的時候大概也不會用到它。這些額外的功能通常帶來的結果就是「分心」，那不是我想要的。</p>

<p>幾個重點：</p>

<ul>
<li>不要把它當電腦用。</li>
<li>不要把它當ipad用。</li>
<li>只要把它當書用。</li>
</ul>


<p>以上是我自己最近使用的一些簡單心得，跟大家分享 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/10/kindle/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[幫你的Octopress增加文章分類]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/KHcHB7RvA3Q/" />
    <updated>2011-12-05T10:00:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/05/add-catetories-to-sidebar-in-octopress</id>
    <content type="html"><![CDATA[<p>發現在Octopress似乎沒有現成可以放在sidebar的分類，於是便自己動手刻一個，順便練一下手感。程式碼短短的，使用方法也很容易，首先你可以按下面程式碼區塊右上角的download，並將檔案存在Octopress的<code>plugins</code>資料夾：</p>

<figure class='code'><figcaption><span> (category_list.rb)</span> <a href='http://blog.eddie.com.tw/downloads/code/octopress/category_list.rb'>download</a></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>
<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>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># encoding: utf-8</span>
</span><span class='line'><span class="k">module</span> <span class="nn">Jekyll</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">class</span> <span class="nc">Site</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">create_category_list</span>
</span><span class='line'>      <span class="n">write_to_tag_cloud</span> <span class="k">if</span> <span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;category_tag_cloud&#39;</span><span class="o">]</span>
</span><span class='line'>      <span class="n">write_to_sidebar</span> <span class="k">if</span> <span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;category_sidebar&#39;</span><span class="o">]</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="c1"># generate category tag list and write to &#39;source/_includes/asides/categories_tag.html&#39;</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">write_to_tag_cloud</span>
</span><span class='line'>      <span class="nb">puts</span> <span class="s1">&#39; =&gt; Creating Categories Tag Cloud&#39;</span>
</span><span class='line'>      <span class="n">lists</span> <span class="o">=</span> <span class="p">{}</span>
</span><span class='line'>      <span class="n">max</span><span class="p">,</span> <span class="n">min</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span>
</span><span class='line'>      <span class="vi">@categories</span><span class="o">.</span><span class="n">keys</span><span class="o">.</span><span class="n">sort_by</span><span class="p">{</span> <span class="o">|</span><span class="n">str</span><span class="o">|</span> <span class="n">str</span><span class="o">.</span><span class="n">downcase</span> <span class="p">}</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">category</span><span class="o">|</span>
</span><span class='line'>        <span class="n">count</span> <span class="o">=</span> <span class="vi">@categories</span><span class="o">[</span><span class="n">category</span><span class="o">].</span><span class="n">count</span>
</span><span class='line'>        <span class="n">lists</span><span class="o">[</span><span class="n">category</span><span class="o">]</span> <span class="o">=</span> <span class="n">count</span>
</span><span class='line'>        <span class="n">max</span> <span class="o">=</span> <span class="n">count</span> <span class="k">if</span> <span class="n">count</span> <span class="o">&gt;</span> <span class="n">max</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>      <span class="n">html</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
</span><span class='line'>      <span class="n">lists</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span> <span class="n">category</span><span class="p">,</span> <span class="n">counter</span> <span class="o">|</span>
</span><span class='line'>        <span class="n">url</span> <span class="o">=</span> <span class="n">get_category_url</span> <span class="n">category</span>
</span><span class='line'>        <span class="n">style</span> <span class="o">=</span> <span class="s2">&quot;font-size: </span><span class="si">#{</span><span class="mi">100</span> <span class="o">+</span> <span class="p">(</span><span class="mi">60</span> <span class="o">*</span> <span class="nb">Float</span><span class="p">(</span><span class="n">counter</span><span class="p">)</span><span class="o">/</span><span class="n">max</span><span class="p">)</span><span class="si">}</span><span class="s2">%&quot;</span>
</span><span class='line'>        <span class="k">if</span> <span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;category_counter&#39;</span><span class="o">]</span>
</span><span class='line'>          <span class="n">html</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot; &lt;a href=&#39;</span><span class="si">#{</span><span class="n">url</span><span class="si">}</span><span class="s2">&#39; style=&#39;</span><span class="si">#{</span><span class="n">style</span><span class="si">}</span><span class="s2">&#39;&gt;</span><span class="si">#{</span><span class="n">category</span><span class="o">.</span><span class="n">capitalize</span><span class="si">}</span><span class="s2">(</span><span class="si">#{</span><span class="vi">@categories</span><span class="o">[</span><span class="n">category</span><span class="o">].</span><span class="n">count</span><span class="si">}</span><span class="s2">)&lt;/a&gt; &quot;</span>
</span><span class='line'>        <span class="k">else</span>
</span><span class='line'>          <span class="n">html</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot; &lt;a href=&#39;</span><span class="si">#{</span><span class="n">url</span><span class="si">}</span><span class="s2">&#39; style=&#39;</span><span class="si">#{</span><span class="n">style</span><span class="si">}</span><span class="s2">&#39;&gt;</span><span class="si">#{</span><span class="n">category</span><span class="o">.</span><span class="n">capitalize</span><span class="si">}</span><span class="s2">&lt;/a&gt; &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="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="vi">@source</span><span class="p">,</span> <span class="s1">&#39;_includes/asides/categories_tag.html&#39;</span><span class="p">),</span> <span class="s1">&#39;w&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
</span><span class='line'>        <span class="n">file</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;&quot;&quot;{% if site.category_tag_cloud %}</span>
</span><span class='line'><span class="s2">&lt;section&gt;</span>
</span><span class='line'><span class="s2">&lt;h1&gt;</span><span class="si">#{</span><span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;category_title&#39;</span><span class="o">]</span> <span class="o">||</span> <span class="s1">&#39;Categories&#39;</span><span class="si">}</span><span class="s2">&lt;/h1&gt;</span>
</span><span class='line'><span class="s2">&lt;span class=&#39;categories_tag&#39;&gt;</span><span class="si">#{</span><span class="n">html</span><span class="si">}</span><span class="s2">&lt;/span&gt;</span>
</span><span class='line'><span class="s2">&lt;/section&gt;</span>
</span><span class='line'><span class="s2">{% endif %}</span>
</span><span class='line'><span class="s2">&quot;&quot;&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="c1"># generate category lists and write to &#39;source/_includes/asides/categories_sidebar.html&#39;</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">write_to_sidebar</span>
</span><span class='line'>      <span class="nb">puts</span> <span class="s1">&#39; =&gt; Creating Categories Sidebar&#39;</span>
</span><span class='line'>      <span class="n">html</span> <span class="o">=</span> <span class="s2">&quot;&lt;ul&gt;</span><span class="se">\n</span><span class="s2">&quot;</span>
</span><span class='line'>      <span class="c1"># case insensitive sorting</span>
</span><span class='line'>      <span class="vi">@categories</span><span class="o">.</span><span class="n">keys</span><span class="o">.</span><span class="n">sort_by</span><span class="p">{</span> <span class="o">|</span><span class="n">str</span><span class="o">|</span> <span class="n">str</span><span class="o">.</span><span class="n">downcase</span> <span class="p">}</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">category</span><span class="o">|</span>
</span><span class='line'>        <span class="n">url</span> <span class="o">=</span> <span class="n">get_category_url</span> <span class="n">category</span>
</span><span class='line'>        <span class="k">if</span> <span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;category_counter&#39;</span><span class="o">]</span>
</span><span class='line'>          <span class="n">html</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;  &lt;li&gt;&lt;a href=&#39;</span><span class="si">#{</span><span class="n">url</span><span class="si">}</span><span class="s2">&#39;&gt;</span><span class="si">#{</span><span class="n">category</span><span class="o">.</span><span class="n">capitalize</span><span class="si">}</span><span class="s2"> (</span><span class="si">#{</span><span class="vi">@categories</span><span class="o">[</span><span class="n">category</span><span class="o">].</span><span class="n">count</span><span class="si">}</span><span class="s2">)&lt;/a&gt;&lt;/li&gt;</span><span class="se">\n</span><span class="s2">&quot;</span>
</span><span class='line'>        <span class="k">else</span>
</span><span class='line'>          <span class="n">html</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;  &lt;li&gt;&lt;a href=&#39;</span><span class="si">#{</span><span class="n">url</span><span class="si">}</span><span class="s2">&#39;&gt;</span><span class="si">#{</span><span class="n">category</span><span class="o">.</span><span class="n">capitalize</span><span class="si">}</span><span class="s2">&lt;/a&gt;&lt;/li&gt;</span><span class="se">\n</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 class="n">html</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;&lt;/ul&gt;&quot;</span>
</span><span class='line'>      <span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="vi">@source</span><span class="p">,</span> <span class="s1">&#39;_includes/asides/categories_sidebar.html&#39;</span><span class="p">),</span> <span class="s1">&#39;w&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
</span><span class='line'>        <span class="n">file</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;&quot;&quot;{% if site.category_sidebar %}</span>
</span><span class='line'><span class="s2">&lt;section&gt;</span>
</span><span class='line'><span class="s2">&lt;h1&gt;</span><span class="si">#{</span><span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;category_title&#39;</span><span class="o">]</span> <span class="o">||</span> <span class="s1">&#39;Categories&#39;</span><span class="si">}</span><span class="s2">&lt;/h1&gt;</span>
</span><span class='line'><span class="si">#{</span><span class="n">html</span><span class="si">}</span><span class="s2"></span>
</span><span class='line'><span class="s2">&lt;/section&gt;</span>
</span><span class='line'><span class="s2">{% endif %}</span>
</span><span class='line'><span class="s2">&quot;&quot;&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">def</span> <span class="nf">get_category_url</span><span class="p">(</span><span class="n">category</span><span class="p">)</span>
</span><span class='line'>      <span class="n">dir</span> <span class="o">=</span> <span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;category_dir&#39;</span><span class="o">]</span> <span class="o">||</span> <span class="s1">&#39;categories&#39;</span>
</span><span class='line'>      <span class="no">File</span><span class="o">.</span><span class="n">join</span> <span class="vi">@config</span><span class="o">[</span><span class="s1">&#39;root&#39;</span><span class="o">]</span><span class="p">,</span> <span class="n">dir</span><span class="p">,</span> <span class="n">category</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/_|\P{Word}/</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/-{2,}/</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">downcase</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">CategoryList</span> <span class="o">&lt;</span> <span class="no">Generator</span>
</span><span class='line'>    <span class="n">safe</span> <span class="kp">true</span>
</span><span class='line'>    <span class="n">priority</span> <span class="ss">:low</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">generate</span><span class="p">(</span><span class="n">site</span><span class="p">)</span>
</span><span class='line'>      <span class="k">if</span> <span class="n">site</span><span class="o">.</span><span class="n">config</span><span class="o">[</span><span class="s1">&#39;category_list&#39;</span><span class="o">]</span>
</span><span class='line'>        <span class="nb">puts</span> <span class="s2">&quot;## Generating Categories..&quot;</span>
</span><span class='line'>        <span class="n">site</span><span class="o">.</span><span class="n">create_category_list</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="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>程式碼寫得有點髒，應該有更漂亮的寫法 :)</p>

<p>再來，請打開根目錄的<code>_config.yml</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>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="c1"># ----------------------- #</span>
</span><span class='line'><span class="c1">#    Categories           #</span>
</span><span class='line'><span class="c1"># ----------------------- #</span>
</span><span class='line'><span class="c1"># create categories page</span>
</span><span class='line'><span class="l-Scalar-Plain">category_list</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span><span class='line'><span class="c1"># use counter after categories</span>
</span><span class='line'><span class="l-Scalar-Plain">category_counter</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span><span class='line'><span class="c1"># category title</span>
</span><span class='line'><span class="l-Scalar-Plain">category_title</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">分類</span>
</span><span class='line'><span class="c1"># create an include categories list in @source/_includes/asides/categories_sidebar.html</span>
</span><span class='line'><span class="c1"># and don&#39;t forget to add &#39;asides/categories_sidebar.html&#39; into @default_asides if you want to enable it.</span>
</span><span class='line'><span class="l-Scalar-Plain">category_sidebar</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span><span class='line'><span class="c1"># create an include categories tag cloud page in @source/_includes/asides/categories_tag.html</span>
</span><span class='line'><span class="c1"># and don&#39;t forget to add &#39;asides/categories_tag.html&#39; to @default_asides if you want to enable it.</span>
</span><span class='line'><span class="l-Scalar-Plain">category_tag_cloud</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span></code></pre></td></tr></table></div></figure>


<p>其中，<code>category_list</code>就是用來啟用是否產生側類分類的；<code>category_counter</code>就是用來決定要不要秀出計數器，<code>category_title</code>是那個區塊的標題，<code>category_sidebar</code>跟<code>category_tag_cloud</code>打開的話，則各會產生兩個用來include的檔案。<code>category_sidebar</code>的效果就是一個一個的排下來，但如果你的文章分類很多可能會讓頁面拉很長，如果不喜歡，也可以改用<code>category_tag_cloud</code>的呈現效果。</p>

<p>產生完檔案還不夠，你還需要在<code>_config.yml</code>加一下你要include的區塊，以下是我自己的設定，請依個人需要修改：</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='yaml'><span class='line'><span class="l-Scalar-Plain">default_asides</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="nv">asides/about.html</span><span class="p-Indicator">,</span> <span class="nv">asides/recent_posts.html</span><span class="p-Indicator">,</span> <span class="nv">asides/categories_tag.html</span><span class="p-Indicator">,</span> <span class="nv">asides/googleplus.html</span><span class="p-Indicator">,</span> <span class="nv">asides/plurk.html</span><span class="p-Indicator">,</span> <span class="nv">asides/recent_comments.html</span><span class="p-Indicator">,</span> <span class="nv">asides/twitter.html</span><span class="p-Indicator">,</span> <span class="nv">asides/links.html</span><span class="p-Indicator">,</span> <span class="nv">asides/advertise.html</span><span class="p-Indicator">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>最後，重新<code>rake generate</code>之後應該就可以看到成果了，就如同你現在正在看的這篇文章的右手邊分類一樣的效果。</p>

<p><span class="info">為了tag cloud看起來不會太擠，你可能會需要用CSS來調整一下<code>line-height</code>。</span></p>

<p>不確定這樣做是不是最好的做法，而且有些程式碼我還是硬寫在Ruby裡的，如果有更好的做法還請不吝告知 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/05/add-catetories-to-sidebar-in-octopress/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[第三梯次Flash/ActionScript 3.0課程]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/Tffhr80hS08/" />
    <updated>2011-12-05T02:50:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/12/05/3rd-actionscript-workshop</id>
    <content type="html"><![CDATA[<p>話說在2007年的時候，我曾經很自以為是的辦過一次Flash/AS課程，那時候用的還是AS2.0，來參加的朋友大概五、六位，地點一開始很克難的選在師大附近某家可以上網的簡餐店(後來才移往我自己公司裡上課)；2009年的年中有再辦過第二梯次，這次用的是AS3.0，地點則是商請某個同行友人幫忙借用他們公司大樓的會議室跟投影設備，這回環境比較好一些，參與人數比較多一點，記得最多有將近快10位朋友來參加。</p>

<p>這兩階梯次都是針對沒學過AS程式的朋友從頭講起的，沒有收費用。</p>

<p>沒意外的話，農曆年完之後再來個第三梯次，用的當然也是AS3.0，同樣也是不會收費用的(視場地規定，也許會有低消或場地費)，屆時再歡迎有興趣想學AS3，但卻不知道從何開始的朋友參加。</p>

<p>也許各位最近聽說&#8221;Flash快不行了，HTML5才是王道&#8221;之類的話，以我看來，Flash並沒有不行，目前大部份的web game都還是用Flash開發的，而且Flash現在還有AIR可以用，能做的事情幾乎跟一般native的應用程式差不多；更何況HTML5也還不是王道，它連標準都還沒定，而且還有最可怕的各家瀏覽器支援問題..雖然我自己也開始在練HTML5 + JavaScript的手感，但這跟Flash行不行無關，純屬個人興趣。</p>

<h3>跟現在的AS讀書會有什麼不同?</h3>

<p><a href="https://www.facebook.com/thestudygroup">AS讀書會</a>目前是演講形式，我相信很多在讀書會聽完，大家只是聽一聽，回家很快就會忘光光，所以如果開課的話，我會要求大家想辦法帶電腦過來現場實作。因為是小班制，所以有問題馬上可以大家一起討論。</p>

<p>沒有什麼不可抗力的事情發生的話，上課頻率大概會是每週一次(可能會是在每週六的下午)，每次約2~3小時，全部上完大概一、二個月，所以如果沒把握能一週固定空出2~3小時的朋友就請把機會讓給別人囉。另外，我會準備每次上課的大綱，讓大家可以在現場練習，還可以帶回家複習。</p>

<h3>對象</h3>

<p>有心想學ActionScript 3.0但不知道從哪邊開始的人，至於想學動畫或設計的話我就幫不上忙了，那不是我的專長 :)</p>

<h3>內容</h3>

<p>從最簡單的基礎(變數、迴圈、function到OOP)，到套用好用的library/framework，可以實際做個小案子出來。</p>

<h3>人數</h3>

<p>大概10~15人</p>

<h3>地點</h3>

<p>應該會在台北市某個靠近捷運、有投影設備、麥克風，而且可以上網的地方(未定，如果有朋友可以推薦就更好了)。</p>

<h3>會有錄影嗎?</h3>

<p>不會 :)</p>

<h3>費用</h3>

<p>最多就是場地費吧 (當然如果有人要付我錢，我會很樂意收下的)</p>

<h3>什麼時候報名?</h3>

<p>應該農曆年過後一、二個月 :)</p>

<p>[2012.2.22 update] 最近不少朋友在問這個還有沒有要繼續，放心，當然有，目前正在編寫教材中。不過因為最近小的手邊的專案正在趕，所以可能進度會慢一些，預計應該可以在三月份開始(希望)。</p>

<h3>真的這麼佛心? 有何目的?</h3>

<p>當然有目的，我的目的很明顯也不怕大家知道：</p>

<ul>
<li>複習我的AS3，程式很久沒寫會忘記</li>
<li>練習講話!!</li>
</ul>


<p>我並沒有打算也沒那個本事要跟電腦補習班搶生意，我只是單純的因為我自己不是資訊相關科系畢業，在自學AS的路上吃過不少苦頭，也知道很多設計師在面臨程式碼的時候的痛苦，希望藉由我的一些經驗分享，讓大家少踩一些雷。</p>

<p>但修行最終還是得靠個人，千萬不要相信來了之後回去就會變強。之前有來參加過的朋友，有的已經在同行業界有不錯的成績，但也有的到現在還是什麼都不會。</p>

<p>屆時歡迎有興趣的朋友來參加，不過抱著只想來看看的心態的朋友就不歡迎了 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/12/05/3rd-actionscript-workshop/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[書摘：slide:ology中文版]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/U23faKbRGjg/" />
    <updated>2011-11-30T06:23:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/30/slideology</id>
    <content type="html"><![CDATA[<p><img src="http://blog.eddie.com.tw/images/2011/book-slideology.jpg" alt="image" /><br />
書名：slide:ology中文版<br />視覺溝通：讓簡報與聽眾形成一種對話</p>

<p>還好是中文版，不然我不知道要看多久才看得完。看完後覺得這真是本不錯的書，提出了許多實戰時候應該注意的&#8221;Do&#8221;跟&#8221;Do Not&#8221;，爾後再上台做簡報的時候可以用得上 :)</p>

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


<h2>書摘</h2>

<ul>
<li>&#8220;不知道為什麼當簡報軟體加進來時，我們便喪失說出好故事的能力&#8221; - 前言</li>
<li>&#8220;我們天生就是視覺溝通者。想想幼稚園：我們的表達方式由蠟筆、黏土推動，不是文字處理機或試算表&#8221; - p.2</li>
<li>&#8220;有些人就是不瞭解，簡報可以多麼有力和感人&#8221; - p.4</li>
<li>&#8220;如果一張投影片超過75個字，就變成一份文件；如果在50字左右，就是大字報&#8221; - p.7</li>
<li>&#8220;真正的簡報焦點應該放在簡報者，以及他們想要傳達的理念和概念&#8221; - p.7</li>
<li>&#8220;聽眾不是閱讀你的投影片，就是聽你說話。他們不會同時做兩件事。所以，問問你自己：重要的是讓他們聆聽，還是讓他們閱讀比較有效?&#8221; - p.7</li>
<li>&#8220;聽眾並不是來看你，他們是來看你能為他們做什麼&#8221; - p.15</li>
<li>&#8220;簡報並不只是關於美學或把東西做得漂亮，而是關於創造意義&#8221; - p.18</li>
<li>&#8220;簡報軟體這種工具，從來就不是設計來腦力激盪或繪圖&#8221; - p.26</li>
<li>&#8220;精彩的簡報應該超越語言、地理、文化的界線。真理就是真理&#8221; - p.37</li>
<li>&#8220;資料投影片要談的不是資料，而是資料的意義&#8221; - p.64</li>
<li>&#8220;要有效傳達你的資料，就必須闡述你希望聽眾採取的結論&#8221; - p.68</li>
<li>&#8220;投影片的目的不在於顯示所有的資料，而是傳達結論和見解&#8221; - p.72</li>
<li>&#8220;使用未加工處理的真實圖像，將會提高聽眾的參與動機&#8221; - p.78</li>
<li>&#8220;身為簡報者，想要成功，就必須像個設計師一樣思考&#8221; - p.83</li>
<li>&#8220;把所有東西放在一張投影片上，是簡報者的懶惰&#8221; - p.93</li>
<li>&#8220;沒有對比，你就死定了&#8221; - p.95</li>
<li>&#8220;使用有人物的圖片時，要確認人看著內容，而非轉過頭或逃離內容&#8221; - p.97</li>
<li>&#8220;如果連續三張投影片都有圖表，它們的軸線應該要一致，即使資料有所不同&#8221; - p.100</li>
<li>&#8220;留白不一定是白色的&#8221; - p.106</li>
<li>&#8220;保有淨空間是好事 &#8211; 擁擠代表設計的失敗&#8221; - p.106</li>
<li>&#8220;將元素分散到多張投影片，每張投影片都獲得應有的注意力，聽眾也因能更好的理解概念而受益&#8221; - p.107</li>
<li>&#8220;聽你演說的人，很可能早就知道你替哪家公司工作。在第一張和最後一張投影片指明自己或公司即可&#8221; - p.117</li>
<li>&#8220;背景是平面、舞台、布景幕 &#8211; 不是主要焦點&#8221; - p.125</li>
<li>&#8220;每個字形都有自己的個性&#8221; - p.142</li>
<li>&#8220;每場簡報最好只結合兩種字型，一種用在大標和副標，另一種用於正文&#8221; - p.143</li>
<li>&#8220;如果你計畫使用大型文字，或將之與圖像結合，請花時間排版文字&#8221; - p.146</li>
<li>&#8220;進入投影片瀏覽模式，觀看66%大小的投影片。如果你還能看到，你的聽眾也可以&#8221; - p.152</li>
<li>&#8220;照片應該要能組成有凝聚力的系統，彷彿是同一位投影師所拍下的作品&#8221; - p.160</li>
<li>&#8220;在視覺資訊出場的那一瞬間，觀看者就會閱讀並處理資訊&#8221; - p.183</li>
<li>&#8220;隱藏元素，直到提到時才讓它們出現&#8221; - p.183</li>
<li>&#8220;不再將投影片當成枴杖，是個漫長的過程，需要時間、耐心、練習&#8221; - p.220</li>
<li>&#8220;簡報者面臨最大的問題，可能在於沒有花時間預演&#8221; - p.220</li>
<li>&#8220;放手的三R原則：刪減(Reduce)、錄音(Record)、重複(Repeat)&#8221; - p.221</li>
<li>&#8220;想一想，如果斷電，你的簡報會發生什麼事&#8221; - p.230</li>
<li>&#8220;單因為你的投影片看起來棒呆了，並不代表這些投影片能傳達有用的意義&#8221; - p.233</li>
<li>&#8220;一旦聽眾發現你在讀文字，他們就會比你更早讀那些文字。結果就是：你跟聽眾不再同步&#8221; - p.234</li>
<li>&#8220;每張投影片都只有一個論點。再多的話，就超過大部份聽眾的能力範圍了&#8221; - p.236</li>
</ul>


<p>本文內容摘錄之文字及影片，其著作權屬原著作人或出版商所有。</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/30/slideology/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[PHPConf Taiwan 2011之CoffeeScript影片]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/DbfYVquoaHg/" />
    <updated>2011-11-25T18:16:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/25/coffeescript-video-on-phpconf-taiwan-2011</id>
    <content type="html"><![CDATA[<p>這是在第一屆的<a href="http://phpconf.tw/2011">PHPConf Taiwan</a>上講的CoffeeScript的錄影，感謝辛苦的拍攝及後製人員，畫質及收音效果相當的好。</p>

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


<p>投影片在這裡：
<a href="http://speakerdeck.com/u/eddie/p/coffeescript-a-better-way-to-write-javascript" target="_blank"><img src="http://blog.eddie.com.tw/images/2011/speakerdeck-coffeescript-in-phpconf-taiwan.jpg" alt="image" /></a>
<a href="http://speakerdeck.com/u/eddie/p/coffeescript-a-better-way-to-write-javascript" target="_blank">View on Speaker Deck</a> | <a href="http://blog.eddie.com.tw/downloads/files/2011/coffeescript.pdf">Download PDF</a></p>

<p>如果想要看得更清楚的話，可以到Youtube切換成HD 1080p模式觀賞。</p>

<p><a href="http://www.youtube.com/watch?v=EbmV-QCYkps&feature=BFa&list=PL9E199DE807DFD9E2&lf=plpp_play_all" target="_blank">全部PHPConf Taiwan 2011的影片播放清單</a></p>

<p>如果大家對於內容有什麼問題，也歡迎在這裡留言，大家一起研究討論 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/25/coffeescript-video-on-phpconf-taiwan-2011/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[CoffeeScript @ 20th Ruby Tuesday]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/5w75vn8Ca_4/" />
    <updated>2011-11-22T12:56:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/22/coffeescript-at-ruby-tuesday</id>
    <content type="html"><![CDATA[<p>感謝<a href="http://ihower.tw/blog/">ihower</a>的邀請，這是今天我在<a href="http://registrano.com/events/ruby-tuesday-20">Ruby Tuesday</a>上用到的投影片。雖然主題跟在<a href="http://phpconf.tw/2011">PHPConf Taiwan</a>的一樣，但因為聽眾們大多對Ruby已經很熟悉，而且CoffeeScript在新版的Rails已經是內建的功能了，沒辦法用同一招繼續騙吃騙喝(同一招不能對聖鬥士用兩次啊)，所以有再特別為Rubyist們調整了內容。
<a href="http://speakerdeck.com/u/eddie/p/coffeescript-in-ruby-tuesday" target="_blank"><img src="http://blog.eddie.com.tw/images/2011/speakerdeck-coffeescript-in-ruby-tuesday.jpg" alt="image" /></a>
<a href="http://speakerdeck.com/u/eddie/p/coffeescript-in-ruby-tuesday" target="_blank">View on Speaker Deck</a> | <a href="http://www.slideshare.net/aquarianboy/coffeescriptrubytuesday" target="_blank">View on Slideshare</a><br />
<a href="http://blog.eddie.com.tw/downloads/files/2011/coffeescript-ruby-tuesday.pdf" target="_blank">Download PDF</a> |
<a href="http://blog.eddie.com.tw/downloads/files/2011/coffeescript-ruby-tuesday-screen.zip" target="_blank">Download Screencast</a></p>

<p>因為Speaker Deck沒辦法全螢幕播放，所以另外也上傳了一份到Slideshare。不過傳到Slideshare的字型好像會跑掉，變超醜..</p>

<p>部份內容是screencast影片，所以沒辦法在slideshare線上看到，有興趣看的人可以另外下載。依舊沒有太多有趣的哏，希望大家會喜歡。</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/22/coffeescript-at-ruby-tuesday/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[幫你的類別增加功能]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/Frhvnn3tsAg/" />
    <updated>2011-11-19T01:29:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/19/extend-functionality-for-your-class</id>
    <content type="html"><![CDATA[<p>CoffeeScript很有趣也很好寫，雖然它提供了許多的語法糖衣(Syntactic sugar)，讓你用短短的幾行程式碼就能換來原來你在JavaScript要做的事。但說白了它本質上還是JavaScript，JavaScript做不到的事，用CoffeeScript一樣也做不到。</p>

<p>不過有些很常做的工作，例字串變換大小寫，雖然JavaScript的字串本身已經有<code>toUpperCase()</code>以及<code>toLowerCase()</code>的功能，但我已經寫習慣Ruby的<code>upcase</code>跟<code>downcase</code>，要記那麼多個名字實在很辛苦，每次都得去google一才下知道要怎麼寫；又如果我想把某個字串重複10次，在Ruby有<code>*</code>可以用，但在JavaScript似乎沒有原生的function可以用.. 有沒有辦法也自己做一些讓自己順手的小工具，讓自己寫程式的時候順利一些呢?</p>

<p>如果你曾經寫過Python或Ruby，就會知道其實它們的類別裡的方法是可以很簡單的被打開再新增或覆寫(open class)，在JavaScript/CoffeeScript也有類似的做法，在CoffeeScript就是使用<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>
<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='coffeescript'><span class='line'><span class="nb">String</span><span class="o">::</span><span class="nv">repeat = </span><span class="nf">(n) -&gt;</span>
</span><span class='line'>  <span class="nb">Array</span><span class="p">(</span><span class="nx">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">join</span> <span class="nx">@</span>
</span><span class='line'>
</span><span class='line'><span class="nb">String</span><span class="o">::</span><span class="nv">downcase = </span><span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">@toLowerCase</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="nb">String</span><span class="o">::</span><span class="nv">upcase = </span><span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">@toUpperCase</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="nb">String</span><span class="o">::</span><span class="nv">find = </span><span class="nf">(str) -&gt;</span>
</span><span class='line'>  <span class="nx">@indexOf</span> <span class="nx">str</span>
</span><span class='line'>
</span><span class='line'><span class="nb">String</span><span class="o">::</span><span class="nv">has = </span><span class="nf">(str) -&gt;</span>
</span><span class='line'>  <span class="p">(</span><span class="nx">@indexOf</span> <span class="nx">str</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span>
</span></code></pre></td></tr></table></div></figure>


<p>編譯出來的JavaScript長這樣：</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">repeat</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">downcase</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">();</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">upcase</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">();</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">find</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">has</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">str</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>其實那個<code>::</code>，用的就是<code>prototype</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>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;a&quot;</span><span class="p">.</span><span class="nx">repeat</span> <span class="mi">10</span>                     <span class="c1"># aaaaaaaaaa</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;this is a book&quot;</span><span class="p">.</span><span class="nx">upper</span><span class="p">()</span>          <span class="c1"># THIS IS A BOOK</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;this is a book&quot;</span><span class="p">.</span><span class="nx">find</span> <span class="s">&quot;book&quot;</span>      <span class="c1"># 10</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;this is a book&quot;</span><span class="p">.</span><span class="nx">has</span> <span class="s">&quot;book&quot;</span>       <span class="c1"># true</span>
</span></code></pre></td></tr></table></div></figure>


<p>程式看起來乾淨多了，也習慣多了，心情也會比較好一些。</p>

<p>PS: 不知道會不會有善心人士會把Python或Ruby一些好用的功能也port一份過來? 還是早就已經有了.. :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/19/extend-functionality-for-your-class/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[CoffeeScript裡的全域變數]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/mubBx-3sI-o/" />
    <updated>2011-11-18T23:54:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/18/global-variables-in-coffeescript</id>
    <content type="html"><![CDATA[<p>在CoffeeScript裡，即使是一個空的.coffee檔，它也會被編譯成這樣：</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='javascript'><span class='line'><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'><span class="p">}).</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>你在.coffee寫的任何變數或function，都是被宣告為區域變數包在裡面，只會在裡面有作用而已。這其實是好事，因為這樣一來與外界隔離，你寫的東西不會去污染到別人寫的，相對的別人寫的東西也不會去弄髒你寫的。但假設因為<strong><em>某些不可抗力</em></strong>，硬是要把變數或function弄成global好讓所有頁面都可以直接使用，也不是沒辦法，你可以直接把變數或function掛在<code>window</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='coffeescript'><span class='line'><span class="nb">window</span><span class="p">.</span><span class="nv">logout = </span><span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">alert</span> <span class="s">&quot;You&#39;ve already logout!&quot;</span> <span class="k">if</span> <span class="nx">confirm</span> <span class="s">&quot;Are you sure to logout?&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>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="nv">root = </span><span class="nx">exports</span> <span class="o">?</span> <span class="k">this</span>
</span><span class='line'><span class="nv">root.logout = </span><span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">alert</span> <span class="s">&quot;You&#39;ve already logout!&quot;</span> <span class="k">if</span> <span class="nx">confirm</span> <span class="s">&quot;Are you sure to logout?&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>第二種寫法看起來比較麻煩，但比較通用。<code>exports</code>是在<a href="http://nodejs.org/">Node.js</a>裡定義的物件，上面第1行的意思是指會先檢查<code>exports</code>是不是已經有定義了，如果這段程式是在Node.js裡執行的話，因為<code>exports</code>是存在的，所以會定義一個<code>root</code>變數並指向它；如果是在一般的網頁上執行，因為沒有<code>exports</code>，所以會定義一個<code>root</code>指向<code>this</code>，也就是<code>window</code>物件 ，所以這樣的寫法的好處就是在網頁或是Node.js都行得通。</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='html'><span class='line'><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;button&quot;</span> <span class="na">value=</span><span class="s">&quot;logout&quot;</span> <span class="na">id=</span><span class="s">&quot;Logout&quot;</span> <span class="na">onclick=</span><span class="s">&quot;logout();&quot;</span> <span class="nt">/&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>但是，如果可以的話，建議還是儘量避免用這種global變數的方式來寫程式，現在的JavaScript越寫越複雜，沒人知道你寫的東西會不會剛好就去衝到誰家寫的library，或是衝到你自己或同事寫的程式碼 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/18/global-variables-in-coffeescript/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[CoffeeScript -> 與 => 的差別]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/T3HEFlg2aAA/" />
    <updated>2011-11-18T00:48:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/18/dash-rocket-vs-fat-arrow-in-coffeescript</id>
    <content type="html"><![CDATA[<p>不知道各位在用CoffeeScript的 <code>-&gt;</code> (dash rocket)在寫function的時候，有沒有發現有另一個長得跟它有點像，但比較胖一點的 <code>=&gt;</code> (fat arrow)，在CoffeeScript的<a href="http://jashkenas.github.com/coffee-script/documentation/docs/grammar.html">source code</a>裡有一段這樣的簡短說明：</p>

<blockquote><p>CoffeeScript has two different symbols for functions. -> is for ordinary functions, and => is for functions bound to the current value of this.</p></blockquote>


<p>在CoffeeScript裡，用 <code>-&gt;</code> 會產生一個Anonymous function，例如：</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='coffeescript'><span class='line'><span class="nv">skinny = </span><span class="nf">(name) -&gt;</span>
</span><span class='line'>  <span class="s">&quot;hello, I&#39;m skinny </span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">skinny</span> <span class="s">&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>
<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='javascript'><span class='line'><span class="kd">var</span> <span class="nx">skinny</span><span class="p">;</span>
</span><span class='line'><span class="nx">skinny</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="s2">&quot;hello, I&#39;m skinny &quot;</span> <span class="o">+</span> <span class="nx">name</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">skinny</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>

<pre><code>hello, I'm skinny eddie
</code></pre>

<p>而 <code>=&gt;</code> 也是會產生Anonymous function：</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='coffeescript'><span class='line'><span class="nv">fatty = </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">=&gt;</span>
</span><span class='line'>  <span class="s">&quot;hello, I&#39;m fatty </span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">fatty</span> <span class="s">&quot;eddie&quot;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>執行結果是：</p>

<pre><code>hello, I'm fatty eddie
</code></pre>

<p>就以程式的執行結果來看，用 <code>-&gt;</code> 跟用 <code>=&gt;</code> 似乎沒什麼兩樣，但看一下用 <code>=&gt;</code> 編譯出來的Javascript程式碼：</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='javascript'><span class='line'><span class="kd">var</span> <span class="nx">fatty</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">__bind</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fn</span><span class="p">,</span> <span class="nx">me</span><span class="p">){</span> <span class="k">return</span> <span class="kd">function</span><span class="p">(){</span> <span class="k">return</span> <span class="nx">fn</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">me</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span> <span class="p">};</span> <span class="p">};</span>
</span><span class='line'><span class="nx">fatty</span> <span class="o">=</span> <span class="nx">__bind</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="s2">&quot;hello, I&#39;m fatty &quot;</span> <span class="o">+</span> <span class="nx">name</span><span class="p">;</span>
</span><span class='line'><span class="p">},</span> <span class="k">this</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>編出了看起來有點複雜的東東西，這串程式碼裡面看起來比較複雜的大概就是那個<code>fn.apply()</code>，我們先來看看那是做什麼的。</p>

<h2>function.call() v.s function.apply()</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>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">who</span> <span class="o">=</span> <span class="s2">&quot;Eddie&quot;</span><span class="p">;</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">doctor</span><span class="p">(){</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="nx">who</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doctor</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<p>這光用我們的人腦執行就猜得到結果是<code>Eddie</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='javascript'><span class='line'><span class="kd">var</span> <span class="nx">who</span> <span class="o">=</span> <span class="s2">&quot;Eddie&quot;</span><span class="p">;</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">doctor</span><span class="p">(){</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">who</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doctor</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<p>多了個<code>this</code>，但執行的結果還是一樣。這裡的<code>this.who</code>其實指的就是整個global的那個<code>who</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">who</span> <span class="o">=</span> <span class="s2">&quot;Eddie&quot;</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">time_lord</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">who</span><span class="o">:</span> <span class="s2">&quot;the real doctor&quot;</span> <span class="p">}</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">doctor</span><span class="p">(){</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">who</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doctor</span><span class="p">();</span>
</span><span class='line'><span class="nx">doctor</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">time_lord</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>其實<code>this</code>指的對像會隨著不同的情境而有所變化。例如我們平常可能會說：「媽! 我在這裡」，如果你是在公司說這句話，「這裡」表示的是公司；如果你是在家裡說這句話，「這裡」表示的是家裡。</p>

<p>再回來看程式碼，在上面程式碼的第8行的呼叫指的this是整個global，在這邊就是<code>window</code>，而第9行指的<code>this</code>則是透過<code>call()</code>方法傳進去的那個物件，程式碼所在的情境變了，所以當第5行要印出<code>this.who</code>的時候，會印出<code>the real doctor</code>。</p>

<p>其實通常沒特別指定的變數或function呼叫，前面的<code>this</code>是可以省略的，所以上面的第8行的<code>doctor()</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='javascript'><span class='line'><span class="nx">doctor</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>執行結果是一樣的。再來繼續再加點變化，<code>call()</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='javascript'><span class='line'><span class="kd">var</span> <span class="nx">who</span> <span class="o">=</span> <span class="s2">&quot;Eddie&quot;</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">time_lord</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">who</span><span class="o">:</span> <span class="s2">&quot;the real doctor&quot;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">doctor</span><span class="p">(</span><span class="nx">real_name</span><span class="p">){</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">who</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;His real name is : &quot;</span> <span class="o">+</span> <span class="nx">real_name</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doctor</span><span class="p">(</span><span class="s2">&quot;Aquarianboy&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nx">doctor</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">time_lord</span><span class="p">,</span> <span class="s2">&quot;No one knows!&quot;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>另外，在JavaScript裡，還有一個跟<code>call()</code>有點像的function叫做<code>apply()</code>，這兩個的功能差不多，最大的差別是<code>apply()</code>傳的第二個參數是陣列，而<code>call()</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='javascript'><span class='line'><span class="kd">var</span> <span class="nx">who</span> <span class="o">=</span> <span class="s2">&quot;Eddie&quot;</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">time_lord</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">who</span><span class="o">:</span> <span class="s2">&quot;the real doctor&quot;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">doctor</span><span class="p">(</span><span class="nx">real_name</span><span class="p">){</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">who</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;His real name is : &quot;</span> <span class="o">+</span> <span class="nx">real_name</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doctor</span><span class="p">(</span><span class="s2">&quot;Aquarianboy&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nx">doctor</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">time_lord</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;No one knows!&quot;</span><span class="p">]);</span>
</span></code></pre></td></tr></table></div></figure>


<p>大概知道在JavaScript裡<code>call()</code>跟<code>apply()</code>的意思之後，再回來看我們剛剛那段CoffeeScript編譯出來的程式碼：</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='javascript'><span class='line'><span class="kd">var</span> <span class="nx">fatty</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">__bind</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fn</span><span class="p">,</span> <span class="nx">me</span><span class="p">){</span> <span class="k">return</span> <span class="kd">function</span><span class="p">(){</span> <span class="k">return</span> <span class="nx">fn</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">me</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span> <span class="p">};</span> <span class="p">};</span>
</span><span class='line'><span class="nx">fatty</span> <span class="o">=</span> <span class="nx">__bind</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="s2">&quot;hello, I&#39;m fatty &quot;</span> <span class="o">+</span> <span class="nx">name</span><span class="p">;</span>
</span><span class='line'><span class="p">},</span> <span class="k">this</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>function一層包一層，return再return，不過大意就是把<code>this</code>當做參數傳進<code>fatty</code>這個function裡的意思。</p>

<h2>什麼時候會用到</h2>

<p>有點離題了..再回來看看CoffeeScript，原來，<code>=&gt;</code>在定義function的同時，還會把<code>this</code>也同時給綁到這個function，雖然<code>this</code>會隨著所在的情境而有所改變，但<code>=&gt;</code>把<code>this</code>給綁進來之後，可以確保在指向<code>this</code>的時候不會指錯人。</p>

<p>為什麼要這樣做? 什麼時候會用到它? 大多是被拿來當做event callback的時候會用得上，來看個範例：</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='javascript'><span class='line'><span class="kr">class</span> <span class="nx">Student</span>
</span><span class='line'>  <span class="nx">constructor</span><span class="o">:</span> <span class="p">(</span><span class="err">@</span><span class="nx">username</span><span class="p">)</span> <span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">say_hello</span><span class="o">:</span> <span class="o">=&gt;</span>
</span><span class='line'>    <span class="nx">alert</span> <span class="s2">&quot;Hello, my name is #{@username}&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="nx">$</span> <span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">eddie</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Student</span><span class="p">(</span><span class="s2">&quot;Eddie&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#student_1&quot;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="nx">eddie</span><span class="p">.</span><span class="nx">say_hello</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>我把<code>eddie.say_hello</code>傳給<code>click</code>做為callback，意思就是當頁面上某個id叫做<code>student_1</code>的元素被點擊之後，就會去執行它，而執行結果是：</p>

<pre><code>Hello, my name is Eddie
</code></pre>

<p>但是如果你把第3行程式碼的<code>=&gt;</code>換成<code>-&gt;</code>的話，執行結果會變成：</p>

<pre><code>Hello, my name is undefined
</code></pre>

<p>為什麼結果是<code>undefined</code>? 前面提到，<code>this</code>會隨著出現在不同的地方而會有不同的意思，如果你是用<code>-&gt;</code>的話，它的<code>this</code>是指向你剛剛點擊的那顆按鈕，而當然那顆按鈕上面不會有<code>username</code>這個屬性，所以印出<code>undefined</code>；如果是用<code>=&gt;</code>的話，它會透過<code>fn.apply()</code>把<code>this</code>給包進來，所以<code>say_hello</code>裡的<code>this</code>，指的就是它自己這個物件，也就是<code>Student</code>類別產生出來的instance，印出來的結果就是你要的了。</p>

<p>細節可以再看看它編譯出來的JavaScript code，大概就可以知道<code>-&gt;</code>跟<code>=&gt;</code>各別做什麼不同的事。</p>

<p>以上，供大家參考，如果有哪邊寫錯再請跟我說 :)</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/18/dash-rocket-vs-fat-arrow-in-coffeescript/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[RVM - Ruby enVironment(Version) Manager]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/BcFk_jDeHfw/" />
    <updated>2011-11-16T15:09:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/16/rvm</id>
    <content type="html"><![CDATA[<p class="info">本篇文章已刊載於<a href="http://www.openfoundry.org/tw/tech-column/8513-rvm-ruby-environment-version-manager" target="_blank">OpenFoundry電子報技術專欄</a>，刊登之內容由專業的OpenFoundry團隊潤稿，此篇為原文。</p>


<h2>前言</h2>

<p>我相信很多人學習<a href="http://www.ruby-lang.org/">Ruby</a>是因為<a href="http://rubyonrails.org/">Ruby on Rails</a>的緣故，但Rails在改版的速度很快，而且有時候改版的幅度不小，例如從以前的2.x版本跳到3.x版本，甚至有些小版號的改版幅度也不小。像是不久前release出來的Rails 3.1.0，就跟3.0.x的架構就差滿多的。就算不談Rails，光是主流的Ruby目前也有1.8.x跟1.9.x的分支，在功能上都有些差異。</p>

<p>這些新推出來的新玩具有的很好玩，不裝起來試一下就會覺得手很癢。你當然可以在你電腦裡安裝這些不同版本新玩具，但畢竟在自己工作的機器上試是有風險的，萬一把環境弄壞了還得花時間想辦法回復。以往我們可能會使用類似<a href="https://www.virtualbox.org/">VirtualBox</a>之類的軟體來模擬作業環境，玩壞了隨時都可以很快的還原或重建一個新的，不過即使這樣還是有點麻煩。</p>

<p>這時候你就需要<a href="http://beginrescueend.com/">RVM</a>(Ruby enVironment(或Version) Manager)了，有了它，你可以安心的在你的電腦裡同時安裝多個不同版本的Ruby而不會打架，例如標準的MRI(Matz&#8217;s Ruby Interpreter)，或是REE(Ruby Enterprise Edition)，甚至是JRuby、MacRuby都沒問題，在RVM裡都可以都可以隨你高興的切換。RVM裡每個版本的Ruby的gem也都是分開裝的，甚至在同一個Ruby版本底下也可以建立不同的gemset，彼此獨立互不影響。如果哪天覺得膩了、不想玩了，可以用<code>rvm remove</code>指令移掉指定的版本；萬一哪天整個不想要玩了，因為RVM是把檔案安裝在<code>/home</code>的個人帳號資料夾底下，所以也不會去影響到系統的設定，不要的時候就整個<code>~/.rvm</code>資料夾砍掉就行了，不會影響原來系統的設定。也就是因為RVM是安裝在你的個人帳號底下，所以你在安裝過程中是不需要root權限的。</p>

<h2>安裝</h2>

<p>以下提到的各項安裝指令，會以<code>Ubuntu 10.10</code>做為示範。</p>

<p>安裝RVM會需要兩項工具<code>curl</code>跟<code>git</code>，如果沒有的話請用<code>apt-get install curl</code>以及<code>apt-get install git</code>指令把這兩個裝起來(安裝這兩個工具你可能需要有系統的root權限)。這兩項工具安裝完成後，請打開你的終端機，貼上這行：</p>

<pre><code>bash &lt; &lt;(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
</code></pre>

<p>它就會開始去下載RVM的安裝程式回來並且自動開始進行安裝。完成後還需要做一下簡單的設定，看你用的shell是哪一套而要修改不同的檔案，假設你用的是ubuntu預設的bash shell的話，你可以直接在終端機裡貼下面這行：</p>

<pre><code>echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;&amp; . "$HOME/.rvm/scripts/rvm" # Load RVM function' &gt;&gt; ~/.bash_profile
</code></pre>

<p>更詳細的安裝說明可以參考官網的<a href="https://rvm.beginrescueend.com/rvm/install/">安裝說明</a>。</p>

<h2>使用</h2>

<p>接著我們來看一些在RVM裡常用的指令，<code>rvm list known</code>會列出目前有哪些可以安裝的列表：</p>

<pre><code>&gt; rvm list known

# MRI Rubies
[ruby-]1.8.6[-p420]
[ruby-]1.8.6-head
[ruby-]1.8.7[-p352]
[ruby-]1.8.7-head
[ruby-]1.9.1-p378
[ruby-]1.9.1[-p431]
[ruby-]1.9.1-head
[ruby-]1.9.2-p180
[ruby-]1.9.2[-p290]
[ruby-]1.9.2-head
[ruby-]1.9.3-preview1
[ruby-]1.9.3[-rc1]
[ruby-]1.9.3-head
ruby-head

# GoRuby
goruby

# JRuby
jruby-1.2.0
jruby-1.3.1
jruby-1.4.0
jruby-1.6.1
jruby-1.6.2
jruby-1.6.3
jruby[-1.6.4]
jruby-head

# Rubinius
rbx-1.0.1
rbx-1.1.1
rbx-1.2.3
rbx-1.2.4
rbx[-head]
rbx-2.0.0pre

# Ruby Enterprise Edition
ree-1.8.6
ree[-1.8.7][-2011.03]
ree-1.8.6-head
ree-1.8.7-head

# Kiji
kiji

# MagLev
maglev[-26852]
maglev-head

# Mac OS X Snow Leopard Only
macruby[-0.10]
macruby-nightly
macruby-head

# IronRuby -- Not implemented yet.
ironruby-0.9.3
ironruby-1.0-rc2
ironruby-head
</code></pre>

<p>長長的一大串，幾乎目前常見的Ruby Interpreter都有了。列表裡的中括號表示那些是可以省略的，所以如果用<code>rvm install</code>來安裝的時候輸入：</p>

<pre><code>&gt; rvm install 1.8.7
</code></pre>

<p>會自動找<code>[ruby-]1.8.7[-p352]</code>這個版本的Ruby來安裝。前面我們提過可以一次安裝多個不同的版本，所以你也可以再裝個1.9.2的版本：</p>

<pre><code>&gt; rvm install 1.9.2
</code></pre>

<p>如果你對最新的Ruby 1.9.3版本有興趣，雖然目前還沒正式release，也可以試著裝一份來試一下它的新功能。再來，我們看看目前已經安裝哪些版本：</p>

<pre><code>&gt; rvm list

rvm rubies

        ruby-1.9.2-p290 [ i686 ]
        ruby-1.8.7-p352 [ i686 ]
</code></pre>

<p>可以看到我電腦上目前裝了2個版本的Ruby(1.8.7跟1.9.2)，這時候我們來看看Ruby的版本：</p>

<pre><code>&gt; ruby -v
ruby 1.8.7 (2010-06-23 patchlevel 299) [i686-linux]
</code></pre>

<p>看到<code>patchlevel</code>只有299，表示這個不是我們剛才安裝的版本，這是系統裡原來就已經裝好的。如果要切換到我們剛才安裝的Ruby 1.9.2版本：</p>

<pre><code>&gt; rvm use 1.9.2
Using /home/eddie/.rvm/gems/ruby-1.9.2-p290
</code></pre>

<p>想少打幾個字的話，<code>use</code>也可以省略：</p>

<pre><code>&gt; rvm 1.9.2
</code></pre>

<p>再來看一下Ruby的版本：</p>

<pre><code>&gt; ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]
</code></pre>

<p>已經切換到Ruby 1.9.2了! 不過有個小問題是，RVM會在下次終端機視窗重開的時候回到預設值(就是系統內建的Ruby版本)，所以如果你希望每次開終端機視窗的時候都會切到Ruby 1.9.2的話：</p>

<pre><code>&gt; rvm 1.9.2 --default
</code></pre>

<p>這樣你每次開終端機視窗就會自動幫你切換到1.9.2版了。如果你想切回到原來系統內建的版本：</p>

<pre><code>&gt; rvm system
</code></pre>

<p>不要了，想砍掉它?</p>

<pre><code>&gt; rvm remove 1.9.2
</code></pre>

<p>就可以把指定的版本移除了，相當便利。如果你整個RVM都不想要了，只要把個人帳號底下的<code>.rvm</code>資料夾整個移除，再把<code>.bash_profile</code>的RVM相關設定改回來，就會整個清潔溜溜了。</p>

<h2>運作原理</h2>

<p>你也許會好奇為什麼RVM可以這麼神奇的切換Ruby的環境，我們來看一下系統的預設PATH：</p>

<pre><code>&gt; echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/eddie/.gem/ruby/1.8/bin:/usr/local/lib/python2.6/dist-packages/django/bin:/home/eddie/.rvm/bin:/home/eddie/.rvm/bin

&gt; which ruby
/usr/bin/ruby

&gt; ruby -v
ruby 1.8.7 (2010-06-23 patchlevel 299) [i686-linux]
</code></pre>

<p>(以上內容是我自己電腦裡的設定，可能跟各位的會有些不同)</p>

<p>再來用RVM切換到1.9.2：</p>

<pre><code>&gt; rvm 1.9.2
Using /home/eddie/.rvm/gems/ruby-1.9.2-p290

&gt; echo $PATH
/home/eddie/.rvm/gems/ruby-1.9.2-p290/bin:/home/eddie/.rvm/gems/ruby-1.9.2-p290@global/bin:/home/eddie/.rvm/rubies/ruby-1.9.2-p290/bin:/home/eddie/.rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/eddie/.gem/ruby/1.8/bin:/usr/local/lib/python2.6/dist-packages/django/bin

&gt; which ruby
/home/eddie/.rvm/rubies/ruby-1.9.2-p290/bin/ruby

&gt; ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]
</code></pre>

<p>事實上，RVM是把不同版本的Ruby安裝在你的個人帳號底下的<code>.rvm</code>資料夾，在你切換不同版本的Ruby的時候，會幫你把系統預設的PATH的最前面加上這個<code>.rvm</code>的資料夾，當你在終端機底下輸入<code>ruby</code>指令的時候，系統原本的<code>/usr/bin/ruby</code>因為在PATH的比較後面，所以感覺會暫時失效而使用RVM版本的Ruby。你可以試著用<code>rvm info</code>來看看RVM幫你做了哪些設定。</p>

<h2>Gem</h2>

<p>在RVM裡，不同版本的Ruby的gem是各別獨立的，來做個簡單的實驗，例如我們先切換到1.9.2底下：</p>

<pre><code>&gt; gem list

*** LOCAL GEMS ***

bundler (1.0.0.rc.5)
json (1.6.1 ruby)
rake (0.9.2 ruby)
rdoc (3.10 ruby)
</code></pre>

<p>再來我們切換到1.8.7，然後安裝Rails：</p>

<pre><code>&gt; rvm 1.8.7
&gt; gem install rails
</code></pre>

<p>然後你就可以看到一大票的安裝訊息，然後我們看看gem的安裝情形：</p>

<pre><code>&gt; gem list

*** LOCAL GEMS ***

actionmailer (3.1.1)
actionpack (3.1.1)
activemodel (3.1.1)
activerecord (3.1.1)
.. 略 ..
rails (3.1.1)
railties (3.1.1)
rake (0.9.2 ruby)
rdoc (3.10 ruby)
sprockets (2.0.2)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
tzinfo (0.3.30)
</code></pre>

<p>安裝了最新版本的Rails 3.1.1，這時候切回去Ruby 1.9.2再看原來的gem list的話，還是原來的樣子，表示gem是跟著不同版本的Ruby獨立安裝的。</p>

<p>要注意的是我們在RVM安裝的任何Ruby版本都跟系統的Ruby無關，即使版號相同也是不同的Ruby，gem也不會安裝到系統的Ruby裡，所以可以放心的玩。基本上你只要發現你在安裝gem的時候會需要root權限的時候，通常你用的就是系統版本的Ruby了。</p>

<h2>Gemset</h2>

<p>Ruby/Rails的世界在進步很快，套件的版本會一直在變，所以很常看到這個狀況：</p>

<pre><code>&gt; gem list
.. 略 ..
rails (3.1.1, 3.1.0, 3.0.9, 3.0.7)
.. 略 ..
</code></pre>

<p>同一個套件就裝了二、三個以上的版本，看了實在有些討厭，而且也不知道會不會遇到版本衝突的問題。如果你跟我一樣有這方面的潔癖，你可以選擇把不用的版本移除掉，不過我會建議你用不同的gemset來管理。例如我想同時在1.9.2版本的Ruby底下同時安裝Rails 2.3.9跟3.1.1版本，來看看怎麼做。</p>

<p>先切換到1.9.2之後，建立一個準備要來裝Rails 2.3.9版的gemset：</p>

<pre><code>&gt; rvm gemset create rails-2.3.9
'rails-2.3.9' gemset created (/home/eddie/.rvm/gems/ruby-1.9.2-p290@rails-2.3.9).
</code></pre>

<p>這邊不一定要跟我一樣用<code>rails-2.3.9</code>，gemset的名字你可以取自己喜歡的。再來建一個給Rails 3.1.1版的：</p>

<pre><code>&gt; rvm gemset create rails-3.1.1
'rails-3.1.1' gemset created (/home/eddie/.rvm/gems/ruby-1.9.2-p290@rails-3.1.1).
</code></pre>

<p>看一下目前的已經建立的gemset：</p>

<pre><code>&gt; rvm gemset list

gemsets for ruby-1.9.2-p290 (found in /home/eddie/.rvm/gems/ruby-1.9.2-p290)
        global
        rails-2.3.9
        rails-3.1.1
</code></pre>

<p>你看到2個我們剛剛建好的gemset，那個global是整個Ruby預設的gemset，如果沒特別指定的話，gem都是安裝到<code>global</code>裡面。再來我們切換到rails-2.3.9：</p>

<pre><code>  &gt; rvm gemset use rails-2.3.9
</code></pre>

<p>來安裝一下Rails 2.3.9版</p>

<pre><code>&gt; gem install rails -v='2.3.9' --no-rdoc --no-ri
Fetching: activesupport-2.3.9.gem (100%)
Fetching: activerecord-2.3.9.gem (100%)
.. 略 ..
Successfully installed activeresource-2.3.9
Successfully installed rails-2.3.9
7 gems installed
</code></pre>

<p>安裝完成，再來切換到rails-3.1.1：</p>

<pre><code>&gt; rvm gemset use rails-3.1.1
</code></pre>

<p>再來做一樣的動作，只是版號改成3.1.1。兩個gemset都裝好之後來看看結果：</p>

<pre><code>&gt; rvm gemset use rails-2.3.9
&gt; rails -v
Rails 2.3.9

&gt; rvm gemset use rails-3.1.1
&gt; rails -v
Rails 3.1.1
</code></pre>

<p>如果你要從別的版本的Ruby直接切換到指定的gemset：</p>

<pre><code>&gt; rvm 1.9.2@rails-3.1.1
</code></pre>

<p>你可以隨你高興的建立、切換gemset，每個gemset都是獨立的。如果玩膩了或玩爛了，想要把rails-2.3.9這個gemset清空的話：</p>

<pre><code>&gt; rvm gemset empty rails-2.3.9
WARN: Are you SURE you wish to remove the installed gems for gemset 'ruby-1.9.2-p290@global' (/home/eddie/.rvm/gems/ruby-1.9.2-p290@global)?
(anything other than 'yes' will cancel) &gt; yes
</code></pre>

<p>清空只會把安裝的gem砍掉，gemset的名字還會在；如果想把整個gemset刪掉：</p>

<pre><code>&gt; rvm gemset delete rails-2.3.9
WARN: Are you SURE you wish to remove the entire gemset directory 'rails-2.3.9' (/home/eddie/.rvm/gems/ruby-1.9.2-p290@rails-2.3.9)?
(anything other than 'yes' will cancel) &gt; yes
</code></pre>

<h2>各別專案設定</h2>

<p>有時候我們會遇到專案A用的是Ruby 1.8.7，專案B用的是Ruby 1.9.2，雖然RVM可以很快的切換，但偶爾忘了換回來可能也會造成一些困擾。這時候你可以在該專案的資料夾底下放一個<code>.rvmrc</code>的檔案，只要簡單的一行設定：</p>

<pre><code>rvm use 1.9.2@rails-3.1.1
</code></pre>

<p>如果後面沒特別指定的話，預設會使用global的gemset。在你第一次進到該資料夾的時候會出現一個提示訊息：</p>

<pre><code>&gt; cd project1
==============================================================================
= NOTICE                                                                     =
==============================================================================
= RVM has encountered a new or modified .rvmrc file in the current directory =
= This is a shell script and therefore may contain any shell commands.       =
=                                                                            =
= Examine the contents of this file carefully to be sure the contents are    =
= safe before trusting it! ( Choose v[iew] below to view the contents )      =
==============================================================================
Do you wish to trust this .rvmrc file? (/tmp/project1/.rvmrc)
y[es], n[o], v[iew], c[ancel]&gt; yes
Using /home/eddie/.rvm/gems/ruby-1.9.2-p290 with gemset rails-3.1.1
</code></pre>

<p>這樣當你下次再用<code>cd</code>指令進到該資料夾的時候，就會自動幫你切換成你指定的Ruby + gemset版本。</p>

<h2>你可能會遇到的麻煩..</h2>

<p>RVM很方便、很好用，但之前在<a href="http://www.openfoundry.org/">OSSF工作坊</a>開Ruby的課的時候也曾經吃過悶虧。RVM在安裝的時候，有些特別的package的安裝需要另外處理，像<code>OpenSSL</code>就是其中一例。就算用系統的<code>apt-get install</code>來安裝也沒用，RVM也是找不到而出現<code>LoadError</code>。需要用以下面這個方式來安裝：</p>

<pre><code>&gt; rvm pkg install openssl
&gt; rvm remove 1.9.2
&gt; rvm install 1.9.2 --with-openssl-dir=$rvm_path/usr
</code></pre>

<p>除了<code>OpenSSL</code>之外，<code>Readline</code>也有類似的狀況，如果你是用RVM在Ubuntu上練習寫Rails的時候特別容易遇到，這點還請多留意。更多詳細內容可<a href="http://beginrescueend.com/packages/">參考這裡</a>。</p>

<h2>結論</h2>

<p>RVM可以快速的在各個版本之間切換，每個版本跟gemset之間也都切得很乾淨，不會影響到原來系統設定，對我這種喜歡嚐鮮、試新玩具又怕把系統搞髒搞爛的人來說，真的是一大福音!</p>

<h2>參考資料</h2>

<ul>
<li>[<a href="https://rvm.beginrescueend.com/">RVM官網</a>]</li>
</ul>

]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/16/rvm/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[當jQuery遇上CoffeeScript]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/IRJVj46UhvQ/" />
    <updated>2011-11-14T11:57:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/14/when-jquery-meets-coffeescript</id>
    <content type="html"><![CDATA[<p>上週的<a href="http://phpconf.tw/2011">PHPConf Taiwan</a>，有幾位朋友在會後問我<a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>要怎麼樣跟jQuery之類的framework整合在一起，會不會打架? 基本上是不會的，CoffeeScript寫出來的東西就是JavaScript，如果會打架，那表示你即使不用CoffeeScript來寫也一樣打架了。</p>

<p>我們來看看要怎麼把jQuery跟CoffeeScript放一起。</p>

<p>簡單的說，<strong>就跟你平常在用jQuery沒什麼兩樣</strong>，例如你要取得頁面上某個元素：</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='coffeescript'><span class='line'><span class="nv">$pokemon = </span><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#pikachu&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>就可以取得頁面上某個id叫做<code>pikachu</code>的元素(這例子是從那本CoffeeScript的書上借來的 orz)。</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='javascript'><span class='line'><span class="nx">$</span><span class="p">().</span><span class="nx">ready</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;hello, jQuery&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>就是在頁面載入完成後跟你打聲招呼的程式，在CoffeeScript裡你就這樣寫：</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='coffeescript'><span class='line'><span class="nx">$</span><span class="p">().</span><span class="nx">ready</span> <span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">alert</span> <span class="s2">&quot;hello jQuery&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>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;hello, jQuery&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>改成CoffeeScript則是：</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='coffeescript'><span class='line'><span class="nx">$</span> <span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">alert</span> <span class="s2">&quot;hello, jQuery&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>其實寫法跟原來的寫法沒什麼兩樣，就一樣<code>$</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;h1&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="s1">&#39;I am clicked&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>意思是「點擊h1元素之後改變它的內容」，改成用CoffeeScript寫的話：</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='coffeescript'><span class='line'><span class="nx">$</span> <span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;h1&#39;</span><span class="p">).</span><span class="nx">click</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">(</span><span class="err">@</span><span class="p">).</span><span class="nx">html</span> <span class="s1">&#39;I am clicked&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>好像已經簡單到我都不好意思要寫這篇了..</p>

<p>如果要寫jQuery的Plugin呢? 舉個簡單的例子，例用Regular Expression來檢查Email格式的小程式，原本可能會長得像這樣：</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='javascript'><span class='line'><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">){</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">.</span><span class="nx">fn</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">isEmail</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">email</span><span class="p">){</span>
</span><span class='line'>      <span class="k">return</span> <span class="sr">/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">email</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">})(</span><span class="nx">jQuery</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>改成用CoffeeScript寫會長這樣：</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='coffeescript'><span class='line'><span class="nv">$ = </span><span class="nx">jQuery</span>
</span><span class='line'>
</span><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">fn</span><span class="p">.</span><span class="nx">extend</span>
</span><span class='line'>  <span class="nv">isEmail: </span><span class="nf">(email) -&gt;</span>
</span><span class='line'>    <span class="o">/^</span><span class="err">\</span><span class="nx">w</span><span class="o">+</span><span class="p">((</span><span class="o">-</span><span class="err">\</span><span class="nx">w</span><span class="o">+</span><span class="p">)</span><span class="o">|</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="err">\</span><span class="nx">w</span><span class="o">+</span><span class="p">))</span><span class="o">*</span><span class="err">\@</span><span class="p">[</span><span class="nx">A</span><span class="o">-</span><span class="nx">Za</span><span class="o">-</span><span class="nx">z0</span><span class="o">-</span><span class="mi">9</span><span class="p">]</span><span class="o">+</span><span class="p">((</span><span class="err">\</span><span class="p">.</span><span class="o">|-</span><span class="p">)[</span><span class="nx">A</span><span class="o">-</span><span class="nx">Za</span><span class="o">-</span><span class="nx">z0</span><span class="o">-</span><span class="mi">9</span><span class="p">]</span><span class="o">+</span><span class="p">)</span><span class="o">*</span><span class="err">\</span><span class="p">.[</span><span class="nx">A</span><span class="o">-</span><span class="nx">Za</span><span class="o">-</span><span class="nx">z0</span><span class="o">-</span><span class="mi">9</span><span class="p">]</span><span class="o">+</span><span class="nx">$</span><span class="err">/.test email</span>
</span></code></pre></td></tr></table></div></figure>


<p>少了一些不必要的大括號跟小括號以及分號，看起來真的清爽多了 :)</p>

<p>另外也有朋友問到，如果CoffeeScript這麼威的話，要不要乾脆把之前寫的JavaScript程式碼全部port成CoffeeScript嗎? 我想這問題的答案就由各位自己評估了。我是因為自己爾後的案子應該會用到Rails 3.x居多，所以會把自己之前寫的一些東西也慢慢的轉過來(但其實也沒多少程式碼)，順便當做練功。</p>
]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/14/when-jquery-meets-coffeescript/</feedburner:origLink></entry>
  
  <entry>
    <title type="html"><![CDATA[閒聊投影片製作與上台表演]]></title>
    <link href="http://feedproxy.google.com/~r/aquarianboy/~3/Ws8Q0YgGOeM/" />
    <updated>2011-11-14T01:42:00+08:00</updated>
    <id>http://blog.eddie.com.tw/2011/11/14/how-do-i-make-my-slide-and-presentation</id>
    <content type="html"><![CDATA[<p><strong>本文有不少個人自以為是的內容，所以請謹慎服用。</strong></p>

<p>我之前工作的某個老闆跟我說過「<strong>每次的上台簡報就是一場表演</strong>」，這句話我一直記在心裡。即然是表演，表演內容固然很重要，但&#8221;說故事&#8221;的方法也很重要，不然內容也許真的很棒，但台下卻睡成一團。</p>

<p>不久前看了我的偶像之一<a href="http://www.xxcoder.net/">Lindsay Fallow(a.k.a Stray)</a>的一份簡報<a href="http://www.slideshare.net/stray_and_ruby/robotlegs-2-and-your-brain">Robotlegs 2 and your brain</a>，真的感覺會做投影片的人就是不一樣，即使人不在現場聽演講，簡報裡也沒有太多的文字說明，光看簡報就能大概知道作者想要表達的意思，這很酷!</p>

<p>所以這回在第一屆的<a href="http://phpconf.tw/2011">PHPConf Taiwan</a>上用的投影片，我也想來試一下不同的簡報風格。</p>

<h2>投影片準備</h2>

<h3>設定方向</h3>

<p>因為我的場次只有20分鐘，要講很詳細是不可能的，而且我猜聽眾們對這個主題應該有些陌生，所以我把投影片設定在入門簡介等級的，目的是讓大家知道或認識這個主題就好。</p>

<h3>軟體選擇</h3>

<p>其實軟體不是重點，沒有什麼&#8221;用XX軟體來做簡報才是王道&#8221;這回事，只要選擇自己順手的工具來做就行了。前面幾場我選擇用HTML5 + <a href="http://imakewebthings.github.com/deck.js/">Deck.js</a>來做，我覺得效果滿ok的。基於自以為自己是個閃客，本來想用Flash來做，但時間有點趕，而且我想做的內容可能會需要更精準的控制元素的位置，所以最後我選擇了Keynote。</p>

<h3>製作概念</h3>

<p>用圖片來取代我想講的話，讓聽眾看到圖片之後能自行腦補我想表達的意思，這是我這回想要試驗的目標。</p>

<p>例如我想表達CoffeeScript因為是最近才出來的，會不會被大家認為&#8221;嫩&#8221;、&#8221;年輕&#8221;、&#8221;不成熟&#8221;的感覺，本來想找嗷嗷待哺的幼鳥，但因為幼鳥的皮膚顏色並不好看，所以最後找了小鴨：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/coffeescript-slide-076.jpg" alt="image" /></p>

<p>再來例如我想表達的是「<strong>JavaScript看起來很容易學、很容易寫，但要寫到夠好卻很不容易</strong>」。閃過腦袋的「簡單」是「a piece of cake」：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/coffeescript-slide-009.jpg" alt="image" /></p>

<p>但即使是一片蛋糕，也是有人可以吃的很難看，滿嘴都是：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/coffeescript-slide-010.jpg" alt="image" /></p>

<p>圖片真的有達到我想表達的意思嗎? 不確定，如果沒有，表示我還有很大的努力空間。</p>

<p>整體而言，我準備投影片的內容大概只佔了<strong>30%</strong>的時間，<strong>60%</strong>的時間在找圖，剩下的<strong>10%</strong>在順投影片。值得嗎? 我覺得這是不同的嘗試，並沒有值不值得的問題。</p>

<h3>自我介紹</h3>

<p>上台表演是個讓大家認識你的好機會，所以在投影片裡放個自我介紹是很重要的。這是我本來的自我介紹頁：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/coffeescript-slide-intro-original.png" alt="image" /></p>

<p>整個都是字，密密麻麻的感覺好像感覺很強大、有幾百年功力的樣子。但我其實並不想在個人頁停留太久，而且寫了一堆，別人也不見得想看，還可能被覺得是在吹噓當年有多勇。真正厲害的角色只要一句：</p>

<blockquote><p>I&#8217;m CEO, Bitch</p></blockquote>


<p>輕描淡寫的一句話，大家就知道他的趴數了。</p>

<p>為了讓自己更快讓別人知道我的比較熟悉的技能，所以我做了這張，跟大家說我是寫Flash的：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/coffeescript-slide-005.jpg" alt="image" /></p>

<p>然後把前面那個都是字的內容縮減成這樣：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/coffeescript-slide-006.jpg" alt="image" /></p>

<p>其實字還是滿多的，所以我不會全部照著唸，在這頁我大概只會停留10秒鐘以內就會離開。至於網站或是聯絡資訊，反正也不會有人想看，所以我在放在最後一張。我把它放在最後一張並不表示不讓它登場。我大概計算過，在我跟大家說謝謝準備下台之後，從我原本站的位置走到我的電腦、關掉投影片，大概有5秒左右的時間，這個時間我預計大家都在拍手，然後我會在這個時候從倒數第二張的QA畫面，切換到最後一張投影片：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/coffeescript-slide-081.jpg" alt="image" /></p>

<h3>字型</h3>

<p>全英文投影片? 英文是很厲害是嗎?</p>

<p>當然不是! 不得不說，中文字型的筆畫多，如果想走精緻路線很吃虧，所以除了我的名字是中文的之外，其它的我選用英文來寫。</p>

<p>為了不讓字型搶了圖片的風采，所以我想找細一點的字型，但如果太細到時候播放出來又擔心看不清楚，所以字型的樣式跟粗細在用的時候是要很注意的。系統裡的字型沒有我看喜歡的，所以我上網找找看有沒有漂亮的字型，後來找到<a href="http://www.fontspace.com/glukfonty/rawengulk">Rawengulk</a>這套字型，樣子看起來像這樣：</p>

<p><img src="http://blog.eddie.com.tw/images/2011/rawengulk-fonts.png" alt="image" /></p>

<p>免費而且可商業使用。雖然它不是等寬字，不過這套字型從最細到最粗看起來都滿舒服的，在視覺上跟圖片應該會滿搭的(個人感覺)。</p>

<p>順便也<a href="http://blog.eddie.com.tw/downloads/files/2011/glukfonty_rawengulk.zip">備份</a>了一下。</p>

<h3>圖片來源</h3>

<p>一開始我是使用Google的圖片搜尋功能，但圖片的尺寸、品質好壞很難控制，而且授權也不見得都有標示清楚。後來才發現<a href="http://www.flickr.com/">Flickr</a>是個很棒的圖片來源，照片多，而且有很多CC(Creative Commons)授權的圖片，只要搜尋的時候加勾選就行了。</p>

<p><img src="http://blog.eddie.com.tw/images/2011/flickr-cc.png" alt="image" /></p>

<p>CC授權的作品大多只要在使用的時候標記作者姓名、出處，而且不做為商業用途的話，幾乎可以無限制的使用，感謝這些人無私的奉獻。</p>

<p>然後因為我還沒辦法做到完全只靠圖片就說故事給大家聽，還是需要一些簡單的字比較容易說明，所以在選擇照片的時候我會特別選擇有適當的留白區塊可以讓我填字的照片。</p>

<h2>上台表演</h2>

<h3>上台前準備</h3>

<p>我大概花了10%的時間在練習講自己的投影片，我儘量要求自己記得所有投影片的順序，這樣我才能不用回頭看一下投影片就可以繼續講下去，腦袋裡本來預計要講的故事不會因為這樣中斷，在講的過程中因為自己知道下一頁要講什麼，也比較不會緊張。</p>

<h3>站的位置</h3>

<p>我不喜歡選擇站在講桌後面講話，除非是要操作電腦。</p>

<p>雖然不是第一次來中研院的這個會議廳，但以前都是當聽眾，不知道前面的舞台有多長多寬、視野如何，所以我一早到會場，試了一下投影機沒問題之後就先去試一下舞台，看看哪個位置是我可以看得到我目前簡報播到哪一頁，還可以看到全部的聽眾，也可以讓大家都看得到我。</p>

<p><img src="http://blog.eddie.com.tw/images/2011/phpconf-standing-point.jpg" alt="image" />
photo by <a href="http://www.flickr.com/photos/othree/">othree</a></p>

<h3>簡報器</h3>

<p>Wii手把真的是個很不錯的簡報器。</p>

<p>Apple雖然有出一隻長得像ipod的遙控器，但它是紅外線的，缺點就是距離短，而且有指向性，只要站太遠或指的角度不對，就沒辦法用。而Wii是使用藍芽跟電腦連結的，不僅距離長，而且不用太刻意指向電腦就可以操作簡報。</p>

<p>有些手機的App可以做到類似的事，但因為手機是平的，不像Wii手把的十字鍵是凸起來的，所以我如果我對這個App不熟的話，可能得先低頭看一下手機的畫面才能操作，而且可能還得一手拿著、另一手來操作，但Wii手把的話則是只要一隻大姆指就可以輕鬆操作了。</p>

<p>除此之外，Wii手把在&#8221;視覺上&#8221;還有某種程度的娛樂效果 :)</p>

<p><img src="http://blog.eddie.com.tw/images/2011/phpconf-wii-remote.jpg" alt="image" /><br />
photo by <a href="http://www.flickr.com/photos/othree/">othree</a></p>

<h3>麥克風</h3>

<p>因為拿一般的無線麥克風的話，會讓我兩隻手都被佔用，沒辦法有其它手勢，所以我最後跟會場借了小蜜蜂來用。</p>

<p>其實我本來想去找像豬哥亮那種可以把麥克風吊在脖子上的東西，然後把自己搞得像夜市叫賣的，我很愛這種不協調的感覺，只是不知道要去哪邊買就是了。</p>

<h3>與台下聽眾互動</h3>

<p>有些人喜歡在演講過程透過問台下聽眾問題來增加與聽眾的互動，但就我觀察，台灣的聽眾普遍都比較害羞，很容易在問問題的時候會遇到沒人要鳥你的情況。所以問問題就要有用一點小技巧，例如「請問台下有沒有人平常的工作是寫JavaScript呢?」這個問題，我用了反面的問法：「請問台下有沒有人平常的工作是&#8221;不用&#8221;寫JavaScript呢?」，即使大家不捧場，也滿容易再接下去講，場面比較不會僵掉或是中斷原本的流程。</p>

<h3>眼睛看哪裡?</h3>

<p>當然要看正妹啊!!(誤)</p>

<p>上台表演難免會抖，而我自己消除緊張的方法，是在講的過程中，快速掃瞄台下對我講的內容有反應的聽眾，反應包括微笑、點頭等表示聽得懂或認同的，然後把比較多的視線停留在這些人身上來增加自己的一些自信，當自信增加到一定程度之後就比較不會抖了。</p>

<h2>結論</h2>

<p>記得要預先盤算你要做的每個動作的目的以及台下聽眾可能會有的反應(也許是笑、也許是問問題，或是丟雞蛋)。每次的表演結束後，如果有錄影的話，請再花點時間看看自己的表演，看看哪邊是有問題的。不要覺得不好意思，別人眼中的你才是真正的你，鏡子裡的那個自己並不是。看看自己的動作、語調，然後利用每次的演講就改掉一些缺點，才會越來越進步。</p>

<p>我一直相信，只要用心的準備每次的表演，台下的聽眾也會用心的回應你的，即使不是當面跟你說，也會在社群網路上看到正面的回應。</p>

<p>一些個人的想法，與大家分享。</p>

<p>自己要檢討的地方：</p>

<ul>
<li>講話依舊有些抖</li>
<li>無謂的手勢太多</li>
<li>時間的掌控不足</li>
</ul>

]]></content>
  <feedburner:origLink>http://blog.eddie.com.tw/2011/11/14/how-do-i-make-my-slide-and-presentation/</feedburner:origLink></entry>
  
</feed>

