<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>ihower { blogging }</title>
	
	<link>http://ihower.tw/blog</link>
	<description>Software development and Programming</description>
	<lastBuildDate>Wed, 23 May 2012 08:58:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ihower" /><feedburner:info uri="ihower" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>JavaScript，我真是搞不懂你啊！@JSDC.TW 2012</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/e6tskoMYmLA/6570</link>
		<comments>http://ihower.tw/blog/archives/6570#comments</comments>
		<pubDate>Wed, 23 May 2012 07:54:25 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6570</guid>
		<description><![CDATA[這是我在 JSDC.TW 给的 Lightning talk: &#8220;JavaScript，我真是搞不懂你啊！&#8221; 的現場錄影。因為投影片其實只是內嵌影片，所以看影片就好了。 講這個題目的目的完全只是娛樂效果(非戰)。因為成為 LT 講者可以免報名進場，所以就厚著臉皮來表演 Wat 看看，聽起來是有得到一些笑聲 XD 如果想進一步知道 JavaScript 為什麼會這樣處理，可以參考 解析 JavaScript，我真是搞不懂你啊！ @JSDC 2012 這一篇文章。]]></description>
			<content:encoded><![CDATA[<p>這是我在 <a href="http://jsdc.tw/2012/">JSDC.TW</a> 给的 Lightning talk: &#8220;JavaScript，我真是搞不懂你啊！&#8221; 的現場錄影。因為投影片其實只是內嵌影片，所以看影片就好了。</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/d_WN6D6SonI" frameborder="0" allowfullscreen></iframe></p>
<p>講這個題目的目的完全只是娛樂效果(非戰)。因為成為 LT 講者可以免報名進場，所以就厚著臉皮來表演 <a href="https://www.destroyallsoftware.com/talks/wat">Wat</a> 看看，聽起來是有得到一些笑聲 XD 如果想進一步知道 JavaScript 為什麼會這樣處理，可以參考 <a href="http://blog.xuite.net/vexed/tech/60612163">解析 JavaScript，我真是搞不懂你啊！ @JSDC 2012</a> 這一篇文章。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/e6tskoMYmLA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6570/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6570</feedburner:origLink></item>
		<item>
		<title>Functional Programming Meetup #1 開放報名中</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/zb8ks4lPAJY/6568</link>
		<comments>http://ihower.tw/blog/archives/6568#comments</comments>
		<pubDate>Wed, 02 May 2012 14:48:39 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Functional]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6568</guid>
		<description><![CDATA[Update: 演講錄影已上傳。 上次 OSDC.TW 演講 FP 時就有提到想辦 Functional Programming 的社群聚會，經過 godfat 和大貓的催促和貢獻 Haskell 講題後，目前報名已經開始了。請前往 Functional Programming Meetup #1，名額所剩不多。]]></description>
			<content:encoded><![CDATA[<p>Update: 演講錄影<a href="http://fpug.tw/post/22770307315/functional-programming-meetup-1">已上傳</a>。</p>
<p>上次 OSDC.TW 演講 FP 時就有提到想辦 Functional Programming 的社群聚會，經過 <a href="http://www.godfat.org/">godfat</a> 和<a href="http://blog.miaout17.net/">大貓</a>的催促和貢獻 Haskell 講題後，目前報名已經開始了。請前往 <a href="http://registrano.com/events/fpug-meetup-1">Functional Programming Meetup #1</a>，名額所剩不多。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/zb8ks4lPAJY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6568/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6568</feedburner:origLink></item>
		<item>
		<title>Functional Programming for Java Developers 讀書摘要</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/ElCMaptJzfI/6305</link>
		<comments>http://ihower.tw/blog/archives/6305#comments</comments>
		<pubDate>Mon, 16 Apr 2012 14:38:21 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Functional]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6305</guid>
		<description><![CDATA[這是我之前念 Functional Programming for Java Developers 一書的摘要記錄。這本書很薄只有90頁，是一本蠻不錯的 Functional Programming 概念入門勸敗書。 近來 Functional Programming (函數式編程，以下簡稱FP) 的重要性提昇就是為了因應 Concurrency 的需求。CPU 朝向多核架構發展，OOP的程式開發方式物件充滿可變狀態，造成撰寫 Concurrency 程式時陷阱多多。 當然，要寫FP不代表一定要用FP語言，還是可以用現成的OO語言去寫。但就像用沒有OO支援的C去寫OO風格，用專門的FP語言還是比較方便。 為何要FP? 作者說雖然是因為 Concurrency 而學 FP，但是後來卻很享受這種 Paradigm Shift (典範轉移)。OO 被發明因為 GUI，後來人們發現可以用來應用在各種領域上。OO 和 FP 都是工具，各有優缺點，但是現在人們碰到所有問題都用 OO 去解，就像你手上有著搥子，在你眼中什麼都看起來像釘子。 FP 不代表比 OO 優越，畢竟 &#8230; <a href="http://ihower.tw/blog/archives/6305">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="http://akamaicovers.oreilly.com/images/0636920021667/cat.gif" alt="" /></p>
<p>這是我之前念 <a href="http://shop.oreilly.com/product/0636920021667.do">Functional Programming for Java Developers</a> 一書的摘要記錄。這本書很薄只有90頁，是一本蠻不錯的 Functional Programming 概念入門勸敗書。</p>
<p>近來 <a href="http://en.wikipedia.org/wiki/Functional_programming">Functional Programming</a> (函數式編程，以下簡稱FP) 的重要性提昇就是為了因應 Concurrency 的需求。CPU 朝向多核架構發展，OOP的程式開發方式物件充滿可變狀態，造成撰寫 Concurrency 程式時陷阱多多。</p>
<p>當然，要寫FP不代表一定要用FP語言，還是可以用現成的OO語言去寫。但就像用沒有OO支援的C去寫OO風格，用專門的FP語言還是比較方便。</p>
<h2>為何要FP?</h2>
<p>作者說雖然是因為 Concurrency 而學 FP，但是後來卻很享受這種 Paradigm Shift (典範轉移)。OO 被發明因為 GUI，後來人們發現可以用來應用在各種領域上。OO 和 FP 都是工具，各有優缺點，但是現在人們碰到所有問題都用 OO 去解，就像<a href="http://en.wikipedia.org/wiki/Law_of_the_instrument">你手上有著搥子，在你眼中什麼都看起來像釘子</a>。</p>
<p>FP 不代表比 OO 優越，畢竟 OO 的好處已經被證實且廣泛應用。而是目前時代不同了，OO 的缺點在某些領域已經到了不可忽視的地步，有些挑戰性的問題用 FP 解更為適合，例如：</p>
<p><span id="more-6305"></span></p>
<p>1. Concurrent</p>
<p>以往我們總是讓最聰明的人去解 Concurrent 問題，小心地注意 Synchronized access to shared。因此絕大部分的開發者不需要煩惱。但是今日CPU多核，Concurrent 需求大增，FP 可以給你正確方式和更高階的 Concurrency 抽象機制來讓這件事更容易。</p>
<p>2. Big data (大部分的程式只是資料處理問題)</p>
<p>當你需要處理 terabytes 等級的資料時，你絕對承受不了 Object 的 overhead，你需要更有效率有最少 overhead 的資料結構跟演算法。ORM 在這問題上是無用的，任何轉換 Relational data 的抽象機制是無用的。FP 可以给你最少的 overhead 來操作這些原始資料，又可以做到 DRY 跟 Reuse 性。用 FP 直接處理原始資料，你不需要 OO 的 overhead。</p>
<p>3. Modular</p>
<p>OO 當初的願景包括 Reusable components，可以直接放到你的 app 中。但是成功的 Library, Framework 案例都是你必須 follow 他們的規則來走，很多 code 還是必須重寫。OO 不算是非常成功在 &ldquo;Component assembly&rdquo;<br />
OO 無限制的彈性破壞了 Reuse，因為如何跟一個物件互動的方式太多了。一個系統有好的限制反而比較 Modular，就像 PC 的成功在於 IBM 設計出 PC 架構。Web 的成功在於 HTTP 的簡單協定。</p>
<p>FP 用標準的 List, map, set 來組織資料，FP 的 functions 避免 side effect。去除 dependencies 讓 function 可以在不同 contexts 都可以直接 resue。</p>
<p>4. Work Faster and Faster</p>
<p>今日對於可以快速 deliver 比精確地模型 domain 還重要，因為我們更看重快速修正的能力，一天可以 deployment 好幾次。OO 強調的 object model 能力似乎可以再三考慮了，FP 可以幫助我們有彈性變化的能力。</p>
<p>5. Simplicity</p>
<p>很多OO的複雜性和middleware都是不必要的。FP 返樸歸真更為簡潔。</p>
<h2>什麼是FP?</h2>
<p>不是有 function 的程式語言就叫做 functional programming language 唷?</p>
<p>最早的 FP 是 Lisp，也是目前第二老的高階程式語言了(Fortran最老)，ML family 包括 Caml, OCaml, F#。最 purity 則是 Haskell，近期有 Clojure, Scala 在 JVM 上。</p>
<p>基本原則：</p>
<p>1. 避免 Mutable State</p>
<p>Mutable value 讓 multithreaded programming 變困難。如果可以 immutable，那就不需要 synchronization 了。</p>
<p>另外，程式也更 correctness 正確，特別是在一個大型系統中一個非 locally 的 mutations，要找 bugs 時特別辛苦。</p>
<p>Java 有提供 final，但是這保險卻不夠。因為 final 的 object 還是可以修改!! 例如容器中的元素。沒有 mutable value 之後，FP 提供了其他有效率的方式來操作容器。</p>
<p>不過，還是有部分的 mutability 是無法避免的，例如IO。但是 FP 鼓勵我們思考 Mutable 的必要，將 Mutable 的部份包裝起來，程式其他部分就是 Immutable 安全的。這些需要 Mutable 的部份可以用 STM 或 Actor 來解決 Concurrency 問題。</p>
<p>2. Function 是一級資料, Lambdas 和 Closures, Higher-Order Functions</p>
<p>First-class value 表示可以當成變數(或參數)直接傳遞，方法也不能回傳一個 function，在 Java 中甚至連 class 都不是 first-class。在 Ruby 中 function 和 class 都是。</p>
<p>(method 和 function 的語意有一點差別，前者多半指物件中的方法，後者則比較廣義，不一定綁在物件或類別上。)</p>
<p>Callback method 的情景是最常需要傳遞 function 的地方，Java 用 anonymous inner class 來解決這個問題。不是不行，只是不同 library 的類別(或介面)和要覆寫的 method 命名都不同，每次都要查。如果程式語言支援統一用 function wrapper 就簡潔多了。這種 anonymous function 又叫作 lambda。closure 指的是可以在 function 指涉到外面的變數。在 Java 有限度支援，inner class 中只可以用外面被 final 的變數。</p>
<p>Function 可以回傳 Function 的能力叫做 Higher-Order Functions，在 Java 中只能用 function wrapper 來做了。</p>
<p>3. Side-Effect-Free Function 沒有副作用</p>
<p>不像OO，FP的 function 不論在什麼 context，執行結果都相同。只要參數列相同，不論什麼情況結果都相同(叫做 referential transparency)。</p>
<p>4. Recursion 遞迴</p>
<p>因為要避免 State (loop counter 就是 mutable 變數)，所以用遞迴處理迴圈。不過，深度遞迴會造成 stack 過深的效能問題，因此 FP 語言多會支援 tail-call recursion 的能力能將運算自動轉成迴圈。可惜的是 Java 沒有這個能力。</p>
<p>5. Lazy Evaluation</p>
<p>要表示無窮數列，不可能全算出來，lazy evaluation 可以在要的時候再計算。lazy evaluation 可以幫助我們需要時才執行昂貴的操作。完全的 lazy evaluation 需要 referential transparency 才辦的到，也就是需要 side-effect-free function 和 immutable value。(只有最 Pure Functional 的 Haskell 預設所有 expressions 都是 lazy)</p>
<p>6. Declarative 風格，而不是 Imperative</li>
<p>OO 基本上也是 Imperative 風格，一行行告訴電腦特定的步驟。</p>
<pre><code># Declarative
def factorial
  if (n==1) return 1
  else return n * factorial(n-1)
end

# Imperative 有許多 mutation step
def factorial
  result = 1
  for (i = 2; i&lt;=n; i++) {
    result *= i
  }
  return result
end
</code></pre>
<p>Declarative 風格也跟 lazy evaluation 很合。跟 mutability 和 side-effect function 則不相容。</p>
<p>無論偏好 static 或 dynamic typing, FP 對於 type design 也有一套看法，除了下一章提到的核心容器 type，還有一件事值得學習：</p>
<p>immutable 表示變數初始一定要有值，也就表示不應該允許 null，null 也常常是 bug 源頭，例如忘記去 check null 的存在。在 Java 中 Null type 就是<a href="http://stackoverflow.com/questions/3495711/why-null-was-called-a-subtype-of-every-reference-type">任何 type 的 subtype</a>。會需要 null 的存在，顯然是因為我們需要一個變數來表示 &ldquo;Optionally&rdquo; 可有可無，那麼何不明顯建立一個 type 處理，例如一個抽象介面 Option 以及它的實體化  subtype (final) Some 和 (final) None 表示一個有一個無。因此在需要 null 的場合，使用 Some 和 None 來包裝。Java 的 type-safe 會保證你不會忘記一定要處理 Option，看是 Some 或 None，這種作法保證了程式的可靠性。</p>
<p>像 Option 介面只允許 Some 和 None 這兩個 final 不能再 subtype 的 type，叫做 Algebraic data type，可以從一種 type 安全變換成另一種 type (下一章會有例子)。跟一般我們設計介面的 abstract data type 不限制 subtype，強調 polymorphic behavior 的用法概念不同。</p>
<h2>資料結構和演算法</h2>
<p>FP 偏好使用核心提供的容器 Lists、Maps、Trees、Sets，不像 OO 愛用物件包裹。根據上一章的FP原則，來實際看一些資料結構和演算法。FP提供了常見的資料結構和對應的 Combinator 操作。</p>
<p>Linked list 也是一種 Algebraic Data Type，只有兩種 subtype: empty 和 non-empty。這跟 Java 的 List type 不一樣，Map 也是 abstract data type。作者用 Java 實作了 functional-style 的 List, Map</p>
<p>Combinator functions: 處理容器的基本三招: 1. filter 2. map 3.fold 很多其他操作都是基於此。這三招又叫作 Combinators，是最厲害的 reusable 建構演算法可以組合出複雜的運算。這三招也讓你不必一直用遞迴。</p>
<p>因為是 immutable，所以變數需要改變時，就要不斷的 Copy 出新值才行。如果碰到大資料，對效能就有問題了。好在 FP 內部實作利用了 Structure sharing 的方式，用 tree 結構避免 full-copy 來有效率的處理。這種資料結構叫做 Persistent Data Structure。</p>
<p>利用 DSL (DSL可以用OO也可以用FP實作) 來包裝 FP 操作，只使用核心資料結構和 Combinators。不需要每樣東西都物件化，OO 操作是錯誤的抽象化層級。</p>
<h2>Function Concurrency</h2>
<p>很喜歡作者的這句話 &ldquo;Multithreaded programming, requiring synchronized access to shared, mutable state, is the assembly language of concurrency&#8221;，每次看 OO 程式語言的 threading 章節都覺得 multithreaded 是神人才能寫的東西，實在太難了。</p>
<p>雖然 immutable 特性已經讓很多 synchronization 不需要了。但是 mutate state 還是有不可避免的時候，這時候可以利用更高抽象層級的 Actors 和 STM 來確保 thread-safe。</p>
<p>Actors 透過 Actor 來做訊息傳遞，每個 Actor 有自己的 queue。實作最好的大概是 Erlang 了。<br />
有趣的是，最早的 Smalltalk 想法還比較像 Actor Model，關鍵是 messaging。</p>
<p>1.只有一個 actor 負責改變狀態，所以其他 code 想改變時，都必須通知唯一的 actor，從而避免 synchronization 問題。<br />
2. 允許多個 actors 修改，會有一個特別的 semaphore message 代表安全。</p>
<p>Actors 風險是如果 scope 太大，會造成 bottleneck。</p>
<p>Java 上目前有兩個好的實作：<a href="http://akka.io">Akka</a> 和 <a href="http://functionaljava.org/">Functional Java</a>。Actors 模型有許多地方都受 Erlang 成功的啟發，包括 Akka 用了 Bridge design pattern 來增加 robustness 和 error recovery 能力。</p>
<p>STM 提供記憶體層級的 ACI (記憶體所以做不到 During，所以不是ACID)。STM 背後的原理是 value 本身還是 immutable 的，如果有改變值，則透過改變 references，加上 Persistent Data Structures 機制增加效率。STM 目前做最好的語言大概是 Clojure。Akka 也有 STM 的實作。</p>
<p>關於 Actor 和 STM 的使用時機比喻，RubyConf 2011 的這場 <a href="http://confreaks.net/videos/702-rubyconf2011-scaling-ruby-with-actors-or-how-i-learned-to-stop-worrying-and-love-threads">Scaling Ruby with Actors, or How I Learned to Stop Worrying and Love Threads</a> 演講我覺得還不錯。</p>
<h2>更好的OO</h2>
<p>OO 編程基本上是 Imperative，而 FP 是 declarative。Imperative 看起來很忙又很多 mutation，容易出錯。<br />
mutable 物件不 thread-safe 而且不易掌控修改。讓物件 immutable，盡量 declarative。雖然有限制，但是保持所有 public 抽象層的 Pure，即使內在不 Pure。</p>
<p>以 LSV 為例，在 OO 中因為繼承的自由跟彈性，很難保證符合，於是透過測試或設計模式來做。例如 Template patterns，但是 FP 的 higher-order functions 就可以做到了，細節在 function argument 再定義即可。</p>
<p>有些人覺得 FP 是不是讓 OO 世界的設計模式無用，其實這是搞混了模式的精神跟實作。某些 GOF 的 pattern 其實根本就是 FP 內建的功能(Singleton, Composite, Command, Iterator等)，有些則可以被取代(Template Method &ndash;> higher-order functions)。</p>
<p>FP 也有自己的模式，例如 Fold 用法和 Pattern matching。Monad 被用在 sequence expressions。Vistor pattern 的用途(go inside the object)則被 Pattern matching 取代。</p>
<p>Pattern matching 蠻像 switch 的加強版，是一種好用的 modularity 工具，可以根據 type 做 data extraction，使用 Pattern matching 來實作新功能而不會污染本來的 type</p>
<p>什麼是好 type 設計? OO modeling 沒錯，但是不精準的 OO code 時卻不無法保證 LSV 的 type 正確性。這就是 OO programming 的問題，domain concept 都在變，不如化作 key-value pairs。當然也有好的 domain concept 是不會變，例如錢，zip codes 等等</p>
<p>作者認為任何放在 collection 裡的都不應該有專屬的 type，讓 filter, map, fold 主導。type wrapper 不值得花費開發。</p>
<p>ORM 跟其他 OO middleware 都是無謂的複雜，用 filter, map, fold 轉換資料形式即可。Domain object 雖然容易了解，但是好處卻不總是值得。越少 code 就越 Agile (Play framework 的 Scala Anorm API 是個好例子)。</p>
<h2>願景</h2>
<p>從 Groovy, JRuby, Jython 等 Scripting 語言開始學FP是最簡單的一步，雖然不是FP語言，但是有許多FP的功能。FP 中，Scala 是作者的最愛，你可以同時有OO，然後慢慢學FP。當然，避免一直待在 OO 舒適圈。Clojure 即使你不愛 Lisp 但也值得一學，Lisp 可是歷久不衰的語言。</p>
<p>如果考慮JVM以外，Haskell可以一試，這是所有FP語言的搖籃。Windows 使用者則可以考慮F#。The Structure and Interpretation of Computer Programs 是經典教科書，作者還推薦讀 <a href="http://www.ibm.com/developerworks/java/library/j-ft1/">Neal Ford&rsquo;s Functional Thinking</a> 和 <a href="http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf">Why Functional Programming Matters</a>。</p>
<p>Java 的 Functional 工具有 <a href="http://functionaljava.org/">Functional Java</a>、<a href="http://code.google.com/p/totallylazy/">Totally Lazy</a> 和 <a href="http://akka.io">Akka</a>。作者期望 Akka 會是接下來幾年 Java 界的明日之星。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/ElCMaptJzfI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6305/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6305</feedburner:origLink></item>
		<item>
		<title>那些 Functional Programming 教我的事 投影片</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/G8q1FnsXTY4/6513</link>
		<comments>http://ihower.tw/blog/archives/6513#comments</comments>
		<pubDate>Sun, 15 Apr 2012 06:12:34 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Functional]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6513</guid>
		<description><![CDATA[這是今天在 OSDC.TW 2012 演講的投影片： 那些 Functional Programming 教我的事 View more presentations from Wen-Tien Chang 這個題目是近年來第一次脫離 Ruby 舒適圈的演講(抖)，準備的時候就發現 Functional Programming 不但講不完(30分鐘的演講教不會寫FP啦)，有些概念又很難，真要講到 &#8220;Pure&#8221; 的 Functional Programming 我連 Monad 都還搞不清楚&#8230;orz 所以本來準備的內容在前一天又狠狠砍掉 1/3，開頭改成用 Concurrency Program 來引人入勝，希望這樣的目的有達成 :)]]></description>
			<content:encoded><![CDATA[<p>這是今天在 <a href="http://osdc.tw">OSDC.TW 2012</a> 演講的投影片：</p>
<div style="width:425px" id="__ss_12543573"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/ihower/fp-osdc2012v2" title="那些 Functional Programming 教我的事" target="_blank">那些 Functional Programming 教我的事</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/12543573" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/ihower" target="_blank">Wen-Tien Chang</a> </div>
</p></div>
<p>這個題目是近年來第一次脫離 Ruby 舒適圈的演講(抖)，準備的時候就發現 Functional Programming 不但講不完(30分鐘的演講教不會寫FP啦)，有些概念又很難，真要講到 &#8220;Pure&#8221; 的 Functional Programming 我連 <a href="http://en.wikipedia.org/wiki/Monad_(functional_programming)">Monad</a> 都還搞不清楚&#8230;orz 所以本來準備的內容在前一天又狠狠砍掉 1/3，開頭改成用 Concurrency Program 來<a href="http://picthiz.com/KQeUOQ">引人入勝</a>，希望這樣的目的有達成 :)</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/G8q1FnsXTY4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6513/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6513</feedburner:origLink></item>
		<item>
		<title>HTTP Verbs: 談 POST, PUT 和 PATCH 的應用</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/mDJcmF_kdUk/6483</link>
		<comments>http://ihower.tw/blog/archives/6483#comments</comments>
		<pubDate>Tue, 20 Mar 2012 10:50:39 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6483</guid>
		<description><![CDATA[在初學REST的這幾年，我都認為這幾個 HTTP Verbs 就是對應 CRUD： POST = 新增 GET = 讀取 PUT = 更新 DELETE = 刪除 後來在設計 API only 的 Web service 時，常常搞不清楚到底要用 PUT 還是 POST，才發現我被 Rails 的鷹架範例誤導了(被框架框住想法了?)，所謂的 PUT 其實也可以用到新增，而且還有一個蠻新的 HTTP Verb 叫做 PATCH，像 Github API 和 Rails 4 &#8230; <a href="http://ihower.tw/blog/archives/6483">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>在初學REST的這幾年，我都認為這幾個 HTTP Verbs 就是對應 CRUD：</p>
<ul>
<li>POST = 新增</li>
<li>GET = 讀取</li>
<li>PUT = 更新</li>
<li>DELETE = 刪除</li>
</ul>
<p>後來在設計 API only 的 Web service 時，常常搞不清楚到底要用 PUT 還是 POST，才發現我被 Rails 的鷹架範例誤導了(被框架框住想法了?)，所謂的 PUT 其實也可以用到新增，而且還有一個蠻新的 HTTP Verb 叫做 PATCH，像 <a href="http://developer.github.com/v3/#http-verbs">Github API</a> 和 <a href="http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/">Rails 4</a> 都開始採用。</p>
<p>PUT 比較正確的定義是 Replace (Create or Update)，例如<code>PUT /items/1</code>的意思是替換<code>/items/1</code>，如果已經存在就替換，沒有就新增。PUT 必須包含<code>items/1</code>的所有屬性資料。</p>
<p>但是這個行為通常不怎麼好用，如果只是為了更新<code>items/1</code>的其中一個屬性，就需要重傳所有<code>items/1</code>的屬性也太浪費頻寬了，所以後來又有新的 <a href="http://tools.ietf.org/html/rfc5789">PATCH Method</a> 標準，可以用來做部分更新(Partial Update)。</p>
<p>用幾個 Ruby code 來舉例吧：</p>
<p>POST 新增：</p>
<pre><code># POST /items
def create
  @item = Item.new
  @item.attributes = { :name =&gt; params[:name],
                      :image =&gt; params[:image] }
  @item.save
end
</code></pre>
<p>PUT 替換(新增或完整更新)，此例中如果image參數沒有傳，會被更新成空：</p>
<pre><code># PUT /items/{id}
def replace
   @item = Item.find_by_id(params[:id])

  unless @item  # if @item.nil?
      @item = Item.new
      @item.id = params[:id]
  end

  @item.attributes = { :name =&gt; params[:name],
                       :image =&gt; params[:image] }
  @item.save
end
</code></pre>
<p>PATCH 部分更新，此例中如果image參數沒有傳，就不會被更新：</p>
<pre><code># PATCH /items/{id}
def patch
   @item = Item.find(params[:id])
  @item.attributes = params.slice(:name, :image)
  @item.save
end
</code></pre>
<p>DELETE 刪除，此例中無論如何 items/1 最後都不存在了</p>
<pre><code># DELETE /items/{id}
def destroy
   @item = Item.find_by_id(params[:id])
  @item.destroy if @item
end
</code></pre>
<p>有時候拘泥於&#8221;語意&#8221;這件事情不容易想清楚設計 REST API 時要用哪一個 HTTP 方法，因為有時候不一定是CRUD的形式。我認為 <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">9.1 Safe and Idempotent Methods</a> 定義中的 &ldquo;Idempotent&rdquo; 特性蠻實用的。idempotent 的意思是如果相同的操作再執行第二遍第三遍，結果還是一樣。根據 HTTP 的規格，GET, HEAD, PUT 和 DELETE 是 idempotent，相同的 Request 再執行一次，結果還是一樣。只有 POST 和 PATCH 不是 idempotent，POST 再執行一遍，會再新增一筆資料，PATCH 則是有不能保證 idempotent 的可能性(徵求例子)。POST 和 PATCH 都不是 idempotent 的操作，這也是為什麼 <a href="http://developer.github.com/v3/#http-verbs">Github API</a> 裡用 POST 當做 PATCH 的相容取代方案。</p>
<p>另一個 HTTP Methods 特性是&#8221;Safe&#8221;，這比較簡單，只有 GET 和 HEAD 是 Safe 操作。Safe 特性會影響是否可以快取(POST/PUT/PATCH/DELETE 一定都不可以快取)。而 Idempotent 特性則是會影響可否 Retry (重試，反正結果一樣)。</p>
<table>
<tr>
<th></th>
<th>Safe?</th>
<th>Idempotent?</th>
</tr>
<tr>
<th>GET</th>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<th>POST</th>
<td>N</td>
<td>N</td>
</tr>
<tr>
<th>PATCH</th>
<td>N</td>
<td>N</td>
</tr>
<tr>
<th>PUT</th>
<td>N</td>
<td>Y</td>
</tr>
<tr>
<th>DELETE</th>
<td>N</td>
<td>Y</td>
</tr>
</table>
<p>透過 Idempotent 的特性，有時候可以幫助你判斷該用哪一個 HTTP Methods。回到前面講 PUT 好像不太好用，例如以瀏覽器為主的 HTML 應用表單，要麻是 POST 新增資料，要麻就是用 PATCH 部分更新已經存在的資料(你不會希望用 PUT 修改個人資料的時候，每次都要重傳照片吧)，因此比較少用到 PUT。這也是為什麼 Rails 4 把表單修改的  PUT 改成 PATCH Method，透過 Rails 鷹架產生出來的 update，其實符合的是 PATCH 行為而不是 PUT。</p>
<p>不過還是有一些我認為蠻適合用PUT的情境，例如訂閱東西該用POST還是PUT呢?</p>
<pre><code>POST /subscriptions
# 還是
PUT /subscriptions/{something_id}
</code></pre>
<p>訂閱東西只有兩個狀態，&#8221;已訂閱&#8221;或&#8221;沒有訂閱&#8221;，這個訂閱的操作再重送幾次，還是&#8221;已訂閱&#8221;，所以我認為蠻符合 PUT 的 idempotent 特性。而對應的取消訂閱 API 想當然就是</p>
<pre><code>DELETE /subscriptions/{something_id}
</code></pre>
<p>另外一個我覺得有趣又實用的 PUT 例子是，設計 API 给可以離線 offline 使用的行動裝置(例如iPhone)。支援 offline 產生的資料，通常會使用 <a href="http://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a> 來產生 ID，這樣就不需要透過中央伺服器管控 ID，方便裝置之間的同步。這樣的情境下，新增資料的 REST API 其實可以提供兩種：</p>
<pre><code>POST /items # 參數帶 uuid=4937973d-e349-460a-a6ad-38625125b24a。如果不帶uuid則由server來產生uuid
# 和
PUT /items/4937973d-e349-460a-a6ad-38625125b24a
</code></pre>
<p>對行動裝置的 client 來說，用POST的問題在於離線環境的不穩定，有可能POST之後沒有收到回傳，因此行動裝置不確定有沒有同步成功，這時候要再重試(retry)，但是用 POST 就爆炸了，因為 server 會再新建一筆 uuid 重複的資料。但是用 PUT 就沒有問題了，PUT 是 Idempotent 的操作，可以重送沒有關係 (可以再搭配 Conditional PUT 的機制，用 ETag 和 Last-Modified Headers 確保沒有覆蓋衝突)</p>
<p>如果是沒有 offline 需求的 client，例如第三方應用，那麼就可以用 POST /items 這個 API，交由 server 來產生 uuid。</p>
<h3>其他參考資料</h3>
<ul>
<li><a href="http://amundsen.com/blog/archives/1122">POST-PUT-PATCH illustrated</a></li>
<li><a href="http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/">PUT or POST: The REST of the Story</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/ihower/~4/mDJcmF_kdUk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6483/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6483</feedburner:origLink></item>
		<item>
		<title>JRuby 安裝與 OpenJDK</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/mbTu_5n4p9c/6374</link>
		<comments>http://ihower.tw/blog/archives/6374#comments</comments>
		<pubDate>Sat, 11 Feb 2012 08:12:30 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6374</guid>
		<description><![CDATA[最近把 JRuby 納入開發的武器之一，幾個你可能會想用 JRuby 的考量： 真 MultiThreading JVM 是一個調教超過十年的 VM 可用 jar 佈署到不同平台(Windows, linux, mac&#8230;etc)。Ruby 程式如果要佈署到 Windows，JRuby 我認為是最好的選擇。 可用 war 佈署到 Java Application Server Android GAE 跨平台的 GUI 工具：Swing, SWT 各種精良的 JVM 函式庫: iText, Akka, Apache Batik (SVG), Lucene(search engine) &#8230; <a href="http://ihower.tw/blog/archives/6374">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>最近把 <a href="http://jruby.org/">JRuby</a> 納入開發的武器之一，幾個你可能會想用 JRuby 的考量：</p>
<ul>
<li>真 MultiThreading</li>
<li>JVM 是一個調教超過十年的 VM</li>
<li>可用 jar 佈署到不同平台(Windows, linux, mac&#8230;etc)。Ruby 程式如果要佈署到 Windows，JRuby 我認為是最好的選擇。</li>
<li>可用 war 佈署到 Java Application Server</li>
<li>Android</li>
<li>GAE</li>
<li>跨平台的 GUI 工具：Swing, SWT</li>
<li>各種精良的 JVM 函式庫: iText, Akka, Apache Batik (SVG), Lucene(search engine) 等等</li>
<li>什麼(奇怪)資料庫都可以連接的 JDBC</li>
</ul>
<h2>安裝</h2>
<p>JRuby 的安裝應該是所有 Ruby 實作中最沒有跨平台問題的吧(笑)。只要 JVM 裝好，去 <a href="http://jruby.org/download">JRuby Download</a> 下載，把 jruby/bin 加到 PATH 就可以用了。如果用 RVM 只要 rvm install jruby 即可。</p>
<p>以 Ubuntu 來說：</p>
<pre>
sudo apt-get install openjdk-6-jre

wget http://jruby.org.s3.amazonaws.com/downloads/1.6.6/jruby-bin-1.6.6.tar.gz
tar zxvf jruby-bin-1.6.6.tar.gz
sudo mv jruby-1.6.6 /opt/jruby

sudo vi /etc/environment 加上 /opt/jruby/bin
</pre>
<h2>OpenJDK</h2>
<p>Mac上其實已經有裝 Apple Inc. 發行的 Java SE 6，不過 Apple 已經宣布不再維護其 Mac 版本了，並把他們的程式貢獻到 Java 的開源版本 OpenJDK 上。也就是說 Mac 上如果想要裝新版的JDK 7 或 8，就是得用 <a href="http://openjdk.java.net/">OpenJDK</a> 啦。請參考 <a href="http://code.google.com/p/openjdk-osx-build/">OpenJDK 7 and 8 for OS/X Snow and Lion</a>，下載 .dmg 安裝，然後你可以透過設定環境變數 JAVA_HOME 來指定 Mac 使用這個版本，或是透過 Utilities > Java Preferences 做全域的預設設定。</p>
<p>根據 JRuby 官網的這一篇<a href="http://blog.jruby.org/2011/12/getting_started_with_jruby_and_java_7/">Getting Started with JRuby and Java 7</a>，Java 7 開始支援動態語言的特性，所以跑起 JRuby 效能更好唷。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/mbTu_5n4p9c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6374/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6374</feedburner:origLink></item>
		<item>
		<title>演講：那些 Functional Programming 教我的事</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/h0eh0Ce1NVE/6423</link>
		<comments>http://ihower.tw/blog/archives/6423#comments</comments>
		<pubDate>Fri, 10 Feb 2012 07:01:31 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Functional]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6423</guid>
		<description><![CDATA[一年一度的台灣 Open Source 界盛事 OSDC.TW 又到了。在連續講了好幾年 Ruby 和 Rails 之後，今年我的研究主題決定什麼都學學看來點不一樣，其中 Functional Programming 是我很看好的一個趨勢，所以來挑戰看看。 以下是我今年的演講摘要： Topic: 那些 Functional Programming 教我的事 Abstract: 隨著 CPU 多核和雲端時代的來臨，並行(concurrency)程式和處理巨量資料的需求日益增加，Functional Programming 開始逐漸嶄露頭角。在這場演講之中，我將介紹什麼是 Functional Programming 典範(paradigm)以及為什麼它開始變的重要，以 Scala, Erlang, Haskell, Java, Ruby, JavaScript 等程式語言為例，希望能夠讓您重新思考OO的本質，屆此拋磚引玉。 Speaker: 張文鈿，網路上的代號為ihower，軟體設計師和Ruby on Rails源碼貢獻者，目前是熱情豆行動樂活科技的技術長。曾擔任日本RubyKaigi 2011、中國RubyConf &#8230; <a href="http://ihower.tw/blog/archives/6423">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>一年一度的台灣 Open Source 界盛事 <a href="http://osdc.tw">OSDC.TW</a> 又到了。在連續講了好幾年 Ruby 和 Rails 之後，今年我的研究主題決定<del>什麼都學學看</del>來點不一樣，其中 Functional Programming 是我很看好的一個趨勢，所以來挑戰看看。</p>
<p>以下是我今年的演講摘要：</p>
<p>Topic: 那些 Functional Programming 教我的事</p>
<p>Abstract:</p>
<p>隨著 CPU 多核和雲端時代的來臨，並行(concurrency)程式和處理巨量資料的需求日益增加，Functional Programming 開始逐漸嶄露頭角。在這場演講之中，我將介紹什麼是 Functional Programming 典範(paradigm)以及為什麼它開始變的重要，以 Scala, Erlang, Haskell, Java, Ruby, JavaScript 等程式語言為例，希望能夠讓您重新思考OO的本質，屆此拋磚引玉。</p>
<p>Speaker: </p>
<p>張文鈿，網路上的代號為ihower，軟體設計師和Ruby on Rails源碼貢獻者，目前是熱情豆行動樂活科技的技術長。曾擔任日本RubyKaigi 2011、中國RubyConf China 2010、台灣RubyConf Taiwan 2010和OSDC.TW歷屆講者。他也是Ruby Taiwan社群創辦人和RubyConf Taiwan大會的主辦人。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/h0eh0Ce1NVE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6423/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6423</feedburner:origLink></item>
		<item>
		<title>RubyConf Taiwan 2011 籌辦心得</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/FQzbbBdoPlE/6015</link>
		<comments>http://ihower.tw/blog/archives/6015#comments</comments>
		<pubDate>Thu, 03 Nov 2011 10:05:46 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[日記]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6015</guid>
		<description><![CDATA[RubyConf Taiwan 2011 Opening &#38; Closing View more presentations from Wen-Tien Chang T客邦的報導：RubyConf Taiwan 2011：5國講者加持，技術交流會登場 OSSF的報導：台灣最具規模的 Ruby 程式語言大會－RubyConf Taiwan 活動結束兩個多月了，應該要來記錄一下想法跟心得，有點雜只好條列了： 辦一天不過癮，講者邀一邀一天已經不夠講啦，再加上我比較喜歡單軌議程，單軌議程聽眾也不用煩惱要聽什麼，時間好控制，更不需要跑來跑去找不到位置坐。所以今年挑戰辦兩天! 雖然如此，好像也不能讓講者講超過太久，會擠壓到休息時間，有反應說太累了 XD 這次的餐點是找喜憨兒餐廳，似乎是還不錯，吃的差不多，不會剩太多。根據以往(我的)經驗，乾脆把早上的餐點當早餐，好像不錯(?) 去年的回饋之一就是希望能夠將議程分成入門和進階，所以今年本來是打算第一天是 Tutorial 議程，第二天才是主議程，然後分開售票。不過後來在安排議程上有點難安排，第一天已經不見得完全是 Tutorial 性質了，加上覺得票一起賣也比較簡單，所以索性也就不做分別了。 邀請 Matz 又失敗了。根據去年經驗，週日 Matz 有家庭日不克出席，所以今年安排週五週六，可惜今年這個日期他又剛好有事了。下次先問他哪一天有空好了。 週五週六的安排，似乎讓大家感到驚訝，週五不是要上班嗎? 本來還以為週五報到率會偏低，沒想到竟然還比週六高一些，真是大感意外。而且留著週日放假讓大家在家睡覺補眠好像挺不錯的。我是覺得如果你工作有用到 Ruby，佔用一個工作天來參加 Ruby 年會一點也不過份，進修也算是工作的一部分。下次辦我還是會辦在週五週六，週日讓腦袋休息，週一再繼續打拼。 這次的 &#8230; <a href="http://ihower.tw/blog/archives/6015">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="width:425px" id="__ss_9055067"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/ihower/rubyconf-taiwan-2011-opening-closing" title="RubyConf Taiwan 2011 Opening &amp; Closing" target="_blank">RubyConf Taiwan 2011 Opening &amp; Closing</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/9055067" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/ihower" target="_blank">Wen-Tien Chang</a> </div>
</p></div>
<ul>
<li>T客邦的報導：<a href="http://www.techbang.com.tw/posts/6822-rubyconf-taiwan-2011-conference-debut">RubyConf Taiwan 2011：5國講者加持，技術交流會登場</a></li>
<li>OSSF的報導：<a href="http://www.openfoundry.org/en/foss-news/8441-interview-of-rubyconf-taiwan">台灣最具規模的 Ruby 程式語言大會－RubyConf Taiwan</a></li>
</ul>
<p><a href="http://rubyconf.tw/2011">活動</a>結束兩個多月了，應該要來記錄一下想法跟心得，有點雜只好條列了：</p>
<ul>
<li>辦一天不過癮，講者邀一邀一天已經不夠講啦，再加上我比較喜歡單軌議程，單軌議程聽眾也不用煩惱要聽什麼，時間好控制，更不需要跑來跑去找不到位置坐。所以今年挑戰辦兩天!</li>
<li>雖然如此，好像也不能讓講者講超過太久，會擠壓到休息時間，有反應說太累了 XD</li>
<li>這次的餐點是找喜憨兒餐廳，似乎是還不錯，吃的差不多，不會剩太多。根據以往(我的)經驗，乾脆把早上的餐點當早餐，好像不錯(?) </li>
<li>去年的回饋之一就是希望能夠將議程分成入門和進階，所以今年本來是打算第一天是 Tutorial 議程，第二天才是主議程，然後分開售票。不過後來在安排議程上有點難安排，第一天已經不見得完全是 Tutorial 性質了，加上覺得票一起賣也比較簡單，所以索性也就不做分別了。</li>
<li>邀請 Matz 又失敗了。根據去年經驗，週日 Matz 有家庭日不克出席，所以今年安排週五週六，可惜今年這個日期他又剛好有事了。下次先問他哪一天有空好了。</li>
<li>週五週六的安排，似乎讓大家感到驚訝，週五不是要上班嗎? 本來還以為週五報到率會偏低，沒想到竟然還比週六高一些，真是大感意外。而且留著週日放假讓<a href="https://twitter.com/#!/tkalu/status/107751784092672001">大</a><a href="https://twitter.com/#!/xdite/status/107741540323049472">家</a>在家睡覺補眠好像挺不錯的。我是覺得如果你工作有用到 Ruby，佔用一個工作天來參加 Ruby 年會一點也不過份，進修也算是工作的一部分。下次辦我還是會辦在週五週六，週日讓腦袋休息，週一再繼續打拼。</li>
<li>這次的 $1500 票價也算是一個門檻，考量到去年的贊助情況，所以把票價定比較高。根據今年好一點的贊助情況，下次應該可以略微調降。要跟 COSCUP 或 OSDC.TW 相比，這種比較專門的研討會拉贊助比較困難些，因此只能夠從門票上彌補。話說回來，$1500 說貴不貴，恐怕也是因人而異。看個某駭客研討會的門票價格之後，覺得沒在怕定太貴的啦(?)</li>
<li>高一點的票價也有一點以價制量的意味，如果辦免錢，想必可以吸引到最多的聽眾，但是也造成了報到率低愛來不來的情況。有人說參加 conference 的目的之一就是可以來交朋友，那麼身為主辦單位，我會希望來參與的人是真正對 Ruby 興趣的人，而不是&#8221;來看看&#8221;的人。想來看看 Ruby on Rails 能做什麼的人太多了，但這不是這場年會的目的。</li>
<li>關於議程，如果好整以暇等著 CFP 結束來挑選，那一定是不夠。身為主辦人一定要主動出擊，我想大概很多社群朋友都被我問過要不要來投(笑)。在議程方向上，我有幾個方向：
<ol>
<li>Ruby != Rails，對很多人來說以為 Rails 就是 Ruby 的全部，但是 Ruby 並不只是 Rails 而已，各位 Ruby 人千萬不要侷限自己。因為最多人用 Rails 開發，所以無可避免的 Rails 主題最多，但是我還是特別希望有更多非 Rails 的主題，至少第二天議程上幾乎都不是 Rails (得到 godfat 大大的讚賞)。這裡是 Ruby conference，而不是 Rails conference。</li>
<li>國外講者之必要，今年有來自美國、日本、香港、德國、法國的講者。還記得我第一次參加 OSDC.TW 的衝擊，絕對是大大提昇你的視野和熱情，增長國際見識。另外，還會激勵你練好英文，哈。另外，COSCUP 總召 pingoo 大大也有<a href="http://www.openfoundry.org/tw/foss-news/8496-interview-of-coscup-2011-organizer-in-chief-pingoo">提到</a>第一手講者的想法。如果沒有第一手講者，那就好像辦讀書會格局而不是 &#8220;Conference&#8221; 了。</li>
<li>國內的 Ruby 社群相對年輕，要找到足以擔當 Keynote 的大師有困難，因此就想到來邀請到國內資深的軟體開發前輩(即使不用Ruby也沒關係，軟體開發的道理都通的)，第一個想到的人選就是 Qing 大大，非常感謝他的支持，他的演講超棒的，非常感動。</li>
</ol>
</li>
<li>關於贊助，感謝銳綸、和多、Optimis 的支持(好像都是我待過的公司XD)，最後一週還有非常婚禮主動來函贊助，真是太佛心了。這次也首度開放個人贊助 (從<a href="http://rubykaigi.org">RubyKaigi</a>那得到的點子)，也是一個開源的辦法。</li>
<li>每次辦都在想好累喔，下次不想辦了，可是活動一結束就在思考下次怎樣可以更好，還可以搞什麼。像是下次想來印衣服、想來辦 Official Party。這次獲得了一些廠商的長期支持承諾，至少以後不用擔心贊助掛零。如果您很喜歡這次的 RubyConf，貴公司願意支持 Ruby Taiwan 社群，建立開發者與廠商的正向循環，歡迎與我聯絡。我相信一場令人感動的 Conference 無形中會影響 Programmer 決定使用 Ruby 當做他第一個(或下一個)專業程式語言，這些新生軍力量將會在未來回饋給廠商。</li>
<li>我非常注重 conference 資料紀錄，特別是 1. conference <a href="http://rubyconf.tw/">網頁</a> 2. 講者 <a href="http://ruby.tw/post/9458498945/rubyconf-taiwan-2011-slides">slides</a> 3. 講者<a href="http://ruby.tw/post/11131617072/rubyconf-taiwan-2011-videos">錄影</a>，我自己也常常演講，我認為這些東西對於講者來說，是很重要的 credit 紀錄。網頁的部分我選擇了靜態網頁放在子目錄下，靜態網頁 HTML 純文字最大的好處，就是十年之後還是可以看，不用擔心平台維護，十年之後 CMS 早不能跑了。錄影的話，想不到場地附的錄影品質意外的好，贊。我本來就有預期講英文的 Ruby 1.9 release manager @yugui 演講會被國外 Ruby 社群引用，果然 <a href="http://www.rubyinside.com/ruby-1-9-3-introduction-and-changes-5428.html">Ruby Inside</a> 和 <a href="http://www.infoq.com/news/2011/11/ruby-193">InfoQ</a> 就報導了，這就是邀請第一手講者的好處，不用自己宣傳就登上主要媒體 XD</li>
<li>最後還是要感謝 OSSF 幫忙場地和支援報到、慕凡幫忙處理餐點、所有講者、贊助商、來幫忙攝影的 miau715、鴨七幫忙將去年 2010 網頁改成 2011。也許明年得考慮增加專職場務了。</li>
</ul>
<p>最後，在這場 Conference 中，我有兩個非常感動的時刻，一個是聽 Qing 大大演講時，另一個是 Lightning Talks (沒有料到可以有這麼多精彩的LT啊)。前輩大師的經驗分享，後輩們快樂地 Hacking，那一瞬間我與現場一百多人的感動和歡樂，我永遠不會忘記。</p>
<p><img src="http://farm7.static.flickr.com/6197/6087930906_9a13a86e68.jpg"></p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/FQzbbBdoPlE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6015/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6015</feedburner:origLink></item>
		<item>
		<title>RubyKoans: 透過單元測試來學習 Ruby 語法</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/Z3qzxOmYruw/6026</link>
		<comments>http://ihower.tw/blog/archives/6026#comments</comments>
		<pubDate>Fri, 09 Sep 2011 04:19:38 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=6026</guid>
		<description><![CDATA[http://rubykoans.com/ 是 EdgeCase 所推出的 Ruby 學習工具。它的特別之處在於它是用單元測試填空題的方式來認識Ruby語法。要執行很簡單，下載之後，輸入 rake 就會開始跑測試了(如何安裝Ruby請參考這裡)，例如以下的測試： def test_arrays_and_ranges assert_equal __, (1..5).class assert_not_equal Array, (1..5) assert_equal __, (1..5).to_a assert_equal __, (1...5).to_a end 其中 __ 的地方就是你要解答的部份，因為是空的，所以顯然測試不會通過(Red)，它會提示你那一行出錯，然後實際的值是什麼： ~/koans] (master) .rvm-$ rake /Users/ihower/.rvm/rubies/ruby-1.9.2-p290/bin/ruby path_to_enlightenment.rb AboutArrays#test_arrays_and_ranges has damaged your karma. The Master says: &#8230; <a href="http://ihower.tw/blog/archives/6026">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://rubykoans.com/">http://rubykoans.com/</a> 是 <a href="http://edgecase.com/">EdgeCase</a> 所推出的 Ruby 學習工具。它的特別之處在於它是用單元測試填空題的方式來認識Ruby語法。要執行很簡單，下載之後，輸入 rake 就會開始跑測試了(如何安裝Ruby請參考<a href="http://ihower.tw/rails3/installation.html">這裡</a>)，例如以下的測試：</p>
<pre>
<code>
  def test_arrays_and_ranges
    assert_equal __, (1..5).class
    assert_not_equal Array, (1..5)
    assert_equal __, (1..5).to_a
    assert_equal __, (1...5).to_a
  end
</pre>
<p></code></p>
<p>其中 __ 的地方就是你要解答的部份，因為是空的，所以顯然測試不會通過(Red)，它會提示你那一行出錯，然後實際的值是什麼：</p>
<pre>
<code>
~/koans] (master) .rvm-$ rake
/Users/ihower/.rvm/rubies/ruby-1.9.2-p290/bin/ruby path_to_enlightenment.rb
AboutArrays#test_arrays_and_ranges has damaged your karma.

The Master says:
  You have not yet reached enlightenment.
  You are progressing. Excellent. 20 completed.

The answers you seek...
  <"FILL ME IN"> expected but was  <Range>.

Please meditate on the following code:
  /Users/ihower/koans/about_arrays.rb:48:in `test_arrays_and_ranges'

mountains are merely mountains
your path thus far [...X______________________________________________] 20/274
</code>
</pre>
<p>當你填入答案之後，就會通過進到下一個測試。你可以看到總共有274題，要寫完也是要花點時間。這模式有趣吧，練完之後應該會對Ruby語法有扎實的認識。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/Z3qzxOmYruw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/6026/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/6026</feedburner:origLink></item>
		<item>
		<title>BDD style unit testing video and slides@RubyKaigi 2011</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/di_fR8WZQ9Y/5983</link>
		<comments>http://ihower.tw/blog/archives/5983#comments</comments>
		<pubDate>Sun, 17 Jul 2011 15:52:03 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=5983</guid>
		<description><![CDATA[BDD style Unit Testing View more presentations from Wen-Tien Chang * [Video recording] * Ruby会議2011 2日目レポート (日文報導) This is my slides and video recording at RubyKaigi 2011 (with speaker’s note every page). It’s my first English presentation and the time &#8230; <a href="http://ihower.tw/blog/archives/5983">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="width:425px" id="__ss_8616157"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/ihower/bdd-style-unit-testing" title="BDD style Unit Testing" target="_blank">BDD style Unit Testing</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/8616157" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/ihower" target="_blank">Wen-Tien Chang</a> </div>
</p></div>
<p>* <a href="http://www.ustream.tv/recorded/16053943">[Video recording]</a><br />
* <a href="http://gihyo.jp/news/report/01/rubykaigi2011/0002?page=3">Ruby会議2011 2日目レポート</a> (日文報導)</p>
<p>This is my slides and video recording at <a href="http://rubykaigi.org/2011/en/schedule/details/17M05">RubyKaigi 2011</a> (with speaker’s note every page). It’s my first English presentation and the time is 30mins, so I only talk about the core value of BDD, basic BDD style syntax, why the syntax matters and some BDD caveats you should know and think.</p>
<p>I’m such nervous and may speak too quickly (only use 25 mins). I asked all attendees and found surprisingly more than half attendees do unit testing and RSpec, which means most attendees already knows unit testing and RSpec. Great! Now I’m afraid of my talk will be too easy :P Anyway, hope this talk can help you realize why we do BDD unit testing and not only because RSpec’s awesome syntax.</p>
<p>BTW, If you’re interested in more RSpec syntax, you can checkout <a href="http://ihower.tw/blog/archives/5438">my RSpec talk</a> at OSDC.TW.</p>
<p>這是我在日本 <a href="http://rubykaigi.org/2011/en/schedule/details/17M05">RubyKaigi 2011</a> 的演講錄影跟投影片(包括講稿)，因為是第一次用英文演講，加上時間只有三十分鐘，所以我只講了BDD最重要的核心概念、最基本的 BDD 風格語法、為何 Syntax 會影響你思考以及一些你應該要知道及思考的 BDD 副作用。</p>
<p>因為用英文講太緊張了，所以一開始講的好像太快了，導致只花了25分鐘，還留了5分鐘沒用完。開講前還問了聽眾有多少人有做單元測試，意外發現超過一半以上舉手，而且大部分都是使用 RSpec。真是太棒了，讓我心底馬上os那我還需要講嗎? XD 無論如何，希望這演講還是可以讓你了解到 BDD 單元測試的核心價值，而不只是因為 RSpec 的 awesome 語法而已。</p>
<p>如果你有興趣看更多 RSpec，可以參考我之前在 OSDC.TW 的 <a href="http://ihower.tw/blog/archives/5438">RSpec</a> 演講。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/di_fR8WZQ9Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/5983/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/5983</feedburner:origLink></item>
		<item>
		<title>RubyConf Taiwan 2011 開放報名</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/HgBAjF4vAsM/5961</link>
		<comments>http://ihower.tw/blog/archives/5961#comments</comments>
		<pubDate>Tue, 12 Jul 2011 15:35:24 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=5961</guid>
		<description><![CDATA[RubyConf Taiwan 2011 開放報名啦。兩天的單軌議程，講者群是去年的兩倍，包括 peepcode.com 站長、Ruby 1.9 release manager @yugui、Compass 作者、Thinking in Java 譯者 Qing 大大以及國內頂尖 Rubyists 和 Rails developers，精采可期，報名從速!! 大會網頁：http://rubyconf.tw/2011 報名網址：registrano]]></description>
			<content:encoded><![CDATA[<p>RubyConf Taiwan 2011 開放報名啦。兩天的單軌議程，講者群是去年的兩倍，包括 <a href="peepcode.com">peepcode.com</a> 站長、Ruby 1.9 release manager <a href="http://twitter.com/yugui">@yugui</a>、<a href="http://compass-style.org/">Compass</a> 作者、Thinking in Java 譯者 <a href="http://www.javaworld.com.tw/roller/qing/">Qing 大大</a>以及國內頂尖 Rubyists 和 Rails developers，精采可期，報名從速!!</p>
<p>大會網頁：<a href="http://rubyconf.tw/2011">http://rubyconf.tw/2011</a><br />
報名網址：<a href="https://registrano.com/events/rubyconf-taiwan-2011/registrations/new">registrano</a></p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/HgBAjF4vAsM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/5961/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/5961</feedburner:origLink></item>
		<item>
		<title>兩個 Ruby 建構 Array 和 Hash 的小技巧</title>
		<link>http://feedproxy.google.com/~r/ihower/~3/JhYup6Xv0pY/5959</link>
		<comments>http://ihower.tw/blog/archives/5959#comments</comments>
		<pubDate>Tue, 05 Jul 2011 04:28:56 +0000</pubDate>
		<dc:creator>ihower</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://ihower.tw/blog/?p=5959</guid>
		<description><![CDATA[Array 我想你可能寫過以下這樣的程式。其中 params[:a] 可以只有一個元素，也可以是陣列。但是為了接下來能夠處理，我們需要轉成陣列 array 變數： array = (params[:a].is_a? Array)? params[:a] : [params[:a]] 這裡我們手動判斷了 params[:a] 是不是陣列，實在是有點 ugly。其實 Ruby 內建的 API 就可以支援下述寫法： array = Array(params[:a]) 無論 params[:a] 是陣列還是單一元素，Array(params[:a])會確保出來一定是陣列。 Hash 你有一個物件或是陣列，你想要轉成 Hash，最常見基本的作法會是先初始一個 hash，然後迭代設定它： hash = {} data.each { &#124;d&#124; hash[d.foo] = d.bar &#8230; <a href="http://ihower.tw/blog/archives/5959">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Array</h3>
<p>我想你可能寫過以下這樣的程式。其中 params[:a] 可以只有一個元素，也可以是陣列。但是為了接下來能夠處理，我們需要轉成陣列 array 變數：</p>
<p><code><br />
array = (params[:a].is_a? Array)? params[:a] : [params[:a]]<br />
</code></p>
<p>這裡我們手動判斷了 params[:a] 是不是陣列，實在是有點 ugly。其實 Ruby 內建的 API 就可以支援下述寫法：</p>
<p><code><br />
array = Array(params[:a])<br />
</code></p>
<p>無論 params[:a] 是陣列還是單一元素，<code>Array(params[:a])</code>會確保出來一定是陣列。</p>
<h3>Hash</h3>
<p>你有一個物件或是陣列，你想要轉成 Hash，最常見基本的作法會是先初始一個 hash，然後迭代設定它：</p>
<pre>
<code>
hash = {}
data.each { |d| hash[d.foo] =  d.bar }
</code>
</pre>
<p>高級一點的，也許會思考怎樣寫成一行，然後想到用 inject：</p>
<pre>
<code>
hash = data.inject({}) { |h,d| h[d.foo] =  d.bar; h }
</code>
</pre>
<p>不過，這裡我要介紹一種我的最愛：</p>
<pre>
<code>
hash = Hash[ data.map {|d| [d.foo, d.bar]} ]
</code>
</pre>
<p><code>Hash[]</code>是一個Ruby內建的API可以把陣列轉成Hash，而且效能非常好，比前兩個方法都好。<code>inject</code>想當然是最慢的，我最不推薦使用。</p>
<p>有人跟我抱怨<code>Hash[]</code>有點 magic 可讀性不佳。可是啊，這是 Ruby &#8220;原生&#8221;的 <a href="http://www.ruby-doc.org/core/classes/Hash.html">Hash API</a>，一點都不 magic。你不知道看不懂跟抱怨程式碼可讀性不佳，我個人認為是兩件事情哩。</p>
<img src="http://feeds.feedburner.com/~r/ihower/~4/JhYup6Xv0pY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ihower.tw/blog/archives/5959/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://ihower.tw/blog/archives/5959</feedburner:origLink></item>
	</channel>
</rss>

