Do..End v.s Braces

話說在 Ruby 裡,Block 可以用 do..end 的方式來寫,也可以用大括號來寫,例如用 do..end 的方式寫:

(1..5).each do |i|
  puts i   # 得到1 2 3 4 5
end

用大括號的方式寫的話:

(1..5).each { |i|
  puts i   # 一樣也是得到1 2 3 4 5
}

不過這兩天在看 The Ruby Way 的時候,看到一段是這樣寫的:

“Note that do and end may be substituted for the braces that delimit a block. There are differences, but they are fairly subtle.”
-- The Ruby Way(2nd edition), Page.22

書裡沒看到特別講到底哪邊不一樣,所以好奇的到處翻了網路上的一些資料,發現原來這兩種寫法的優先順序有一些些的不一樣,來看一段範例:

my_array = [1, 2, 3, 4, 5]

p my_array.map { |item|
  item * 2  # 得到[2, 4, 6, 8, 10]
}

p my_array.map do |item|
  item * 2  # 得到[1, 2, 3, 4, 5]
end

為什麼結果跟預期的不一樣? 原來,因為省略了一些小括號,第二段的程式碼本來的意思是:

p(my_array.map do |item| item * 2 end)  # 得到[2, 4, 6, 8, 10]

但卻因為 do..end 的優先順序比較小,原式被解析成:

p(my_array.map) do |item| item * 2 end # 得到[1, 2, 3, 4, 5]

結果後面的 do..end 還沒開始跑,my_array.map 就先被 p 給印出來了..而用大括號的寫法的優先順序比較高,則不會有這個困擾。這樣那到底什麼時候要用 do..end? 什麼時候要用大括號? 還是乾脆全部都用大括號就好?

基本上如果 Block 的執行結果是會有回傳值的,那就建議用大括號來寫,其它的大致上都可以用 do..end 來寫。

果然魔鬼都躲在細節裡!

如果寫得有錯再請不吝指正,感謝!

關於AS讀書會

關於AS讀書會

昨天是第四回的 AS 讀書會,沒想到竟然能辦到第四回,真的太感謝大家的支持,到目前為止,每回的報名人數都一直在90~110 人之間,比我想像的多很多。

沒關係,人多也有人多的玩法。

其實我沒特別跟大家說明,不過如果大家有注意到的話,每次上台分享的講者,我會刻意安排一位前輩搭配相對比較不那麼老鳥的新鳥。老鳥們通常有豐富的業界或講課的經驗,通常可以給我們帶來很完整的演出,而新鳥雖然也許講話會緊張,或可能會有些小狀況,但也常帶來一些”原來可以這樣玩”的新想法。

上台表演跟坐在底下聽,真的是完全兩個不同的世界

會這樣安排的原因是我想讓新鳥也有磨練的舞台,希望讓他們有一天也變成老鳥,然後再來提攜新的新鳥,這樣循環下去。我真心的希望可以藉由這樣的形式來達到另一種的“人人有功練”的理想,所以每次在向老鳥取經的同時,若新鳥們在表演時有些小的狀況的話,也還請各位多多包涵。

如果你也想上台分享心得,或是對某個主題/神人有興趣的,請別客氣的跟我說,狀況許可的話我再來幫忙橋時間。

我想這樣的聚會除了聽大家心得分享之外,會中、會後的時間,同好交流才是我覺得最重要的。我看到大家在休息時間大多不會只是坐在椅子上休息,而會起來找人聊天,這樣很棒!

你也想認識高手神人們嗎? 下次別害羞,名片拿上手,上前去說聲「您好,我是 XXX,久仰大名..」,別擔心碰壁,這些高手神人們都很 nice 的。

而辦這個聚會對我個人我有什麼好處? 其實我賺很大:

  • 講話似乎有比較不會抖,人也比較不會晃、也不會飄來飄去
  • 見識到老鳥們是怎麼”表演”的
  • 學到不少辦活動的眉角,例如橋人、橋時間、橋場地等..

這些經驗值都不是花錢去上課就學得到的,我真的賺到了!!

最後

  • 只要大家願意繼續支持,我們就讓這個聚會繼續辦下去。
  • 希望可以在一年內辦超過 12 場次。
  • 誠徵願意跟大家分享心得的講者。

若有任何建議或想法,請別客氣的讓我知道。

感謝大家的支持!

Learning Something New

Learning Something New

最近寫不太出技術相關的東西,那就來個比較閒聊(嘴砲)性質的主題吧!

在第三回的 AS 讀書會上,maso 兄的 talk 裡的第一張投影片寫著:

“人活得好好的,幹嘛寫 app?”

當下我也覺得,真的,人活得好好的,幹嘛找一些自己不熟的新東西來砸自己的腳?

AS2 寫得好好的,幹嘛要學什麼 AS3?
Flash 寫得好好的,幹嘛要寫什麼 iOS app?
PHP 寫得好好的,幹嘛要學什麼 Ruby/Rails?

Amazon Web Services 之門外漢心得

雲端,雲端,大家都在講雲端,不過我這種第三類組畢業的學生,沒有什麼的理論基礎,也不喜歡講理論(不過聽李教授說人死了之後就會在雲端了),僅就我自己最近試玩幾天 Amazon 的 EC2 心得與大家分享。

Faster Array Concatenation in AS3

前不久在 Grant Skinner 大人的 twitter 上看到這個:

Just discovered a handy trick for merging two arrays in JS: arr1.push.apply(arr1, arr2);
- @gskinner

真神奇,原來 Function.apply 還可以這樣玩,而且這招似乎在 AS3 上也可行,直接寫幾行程式碼測一下:

function test_concat():void
{
    trace("== TEST Array Concat ==");
    var array1:Array = [1, 2, 3];
    var array2:Array = ['a', 'b', 'c'];
    var timer_start = getTimer();
    for (var i:int = 0; i< 10000; i++)
    {
        array1 = array1.concat(array2);
    }
    var timer_end = getTimer();
    trace("the length of array1 is : " + array1.length);
    trace("== " + (timer_end - timer_start) + " miniseconds ==");
}

function test_push_and_apply():void
{
    trace("== TEST Array Push and Apply ==");
    var array1:Array = [1, 2, 3];
    var array2:Array = ['a', 'b', 'c'];
    var timer_start = getTimer();
    for (var i:int = 0; i< 10000; i++)
    {
        array1.push.apply(array1, array2);
    }
    var timer_end = getTimer();
    trace("the length of array1 is : " + array1.length);
    trace("== " + (timer_end - timer_start) + " miniseconds ==");
}

// 測試
test_concat();
trace("");
test_push_and_apply();

我的環境:

  • Macbook Pro
  • CPU : Intel Core 2 Duo 2.4 GHz
  • RAM : 4 GB

執行結果:

== TEST Array Concat ==
the length of array1 is : 30003
== 4119 miniseconds ==

== TEST Array Push and Apply ==
the length of array1 is : 30003
== 5 miniseconds ==

array1 最後結果內容是一樣的,但花的時間差非常大,我想這其中主要的差異應該是在於 Array.concat 每次都會產生一個新的 array,而且還得再 assign 給原來的 array 的緣故。

後來還有看到這篇,野中さん有在 wonderfl 上做了幾個實驗,結果發現跟這兩個 array 的大小有關。不過在我的機器上好像在試不出來差異,不知道是不是我哪邊有錯,即使調整兩個 array 的大小,Function.apply 的速度都是遠大於 Array.concat 的。

update: 是我自己耍笨,測試數字請見連結裡野中さん的那三個測試。

I may be wrong, please correct me if there’s anything wrong :)

Category in Objective-C

Category in Objective-C

OOP 的精神之一,就是如果你想研發一台新款式的車子,你並不需要重新發明輪子,通常的做法會去繼承某個現有的”車子類別”,然後加上你要的功能跟屬性,改一改就變成一款新的車子可以來騙錢了。

不過有時候你想幫原來的類別加功能,但又不想動到原來的程式碼,例如你可能下載了某款功能超強的 2D 物理引擎程式碼,但因為某些小地方寫的不合你的需求,於是你便動手改原始碼來加功能。這當然沒問題,但萬一原作出新的版本,你要不就選擇維持自己原來的版本不 update,不然就是 update 之後,你原來加在舊版本的程式碼得再重貼一次到新版。