高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

Flashers on Google+

image

來勢洶洶的Google+,有人一用了就決定搬家了,有人覺得還好,沒多好用。Google+會不會讓社群網站的版圖重新洗牌呢? 我沒有預言的特異功能,這就留給時間來證明了。

不過的確是有一些國內外的Flasher/ASer也上去註冊了帳號,至於本人是不是真的會搬過來經營,還是留在原本的Twitter/Facebook,這就看個人喜好了。

以下列出了一些我目前在Google+上有看到的Flasher,如果有興趣可以參考看看。我列出來的名單有的是常見面、常聊天的朋友,有的是AS讀書會的朋友,有的是工作上有合作,有的只有在網路上交流過。沒列出來的不代表就不是高手,而是小的我人面不夠廣,認識的人實在不多,或是還沒有這個緣份能認識到這些高手,所以這個名單歡迎大家來補充。

先聲明一下,列這個名單的心態,只是單純的想讓更多的朋友能認識更多的Flasher,也許能透過社群網站知道這些高手們最近在研究什麼心得,或是有新的徵才資訊,或是有案仔要找這些人合作.. 其實很單純的。不過如果有不希望被列出來的也請跟我說,我會馬上處理。

提醒

提醒大家一下,在網路上發言、加好友請記得遵守網路禮儀,特別是Google+的社交圈的規則跟Facebook/Twitter/Plurk是不太一樣的,加了對方之後,即使對方沒把你加入他的社交圈,他還是可能得看到你發表的訊息,這點請多留意。

以下名單依英文字母先後排序,並且可能隨時會更新,最後更新日期:2011/7/21

國外

國內

最後,如果大家不嫌棄,這是小的我自己的

http://www.eddie.com.tw/+ SHAMELESS PROMOTION!!

我想這個名單並沒辦法包括所有的Flasher,我相信還有許多業內的高手是我還沒福份認識到的,至少日本跟大陸的那邊的神人們我還沒機會遇到。以上,如果不希望被列出來的,請跟我說,我會馬上拿下來;如果有知道漏了誰的,或是只是單純的想交朋友的,也歡迎在底下留言補充囉。

記住你青春無畏的樣子

image

其實只是一篇沒什麼內容的口水文!

最近在整理東西的時候發現一枚我在十多年前刻的印章,這是第一次出來闖江湖用的名號。(認識我十年或以上的朋友也許還記得這個當年自以為是的名號)。

正所謂初生之犢不畏虎,年輕時候在學校幫忙寫校務系統,才剛學會用ASP寫點簡單的資料庫新增、修改、刪除功能,然後就自以為放眼望去沒高手了;連在BBS上回答別人問題,也常丟RTFM出來(現在好像也差不多,在PTT Flash版也常叫人去翻F1手冊),現在想想真不知道當年哪來的自信。

不過話說回來,雖然年輕氣盛,但卻很敢試新的玩具,很敢到處挑戰權威,到處筆戰,什麼沒在怕;反而現在年紀大了,不只學習能力跟記憶體有變差的趨勢,不知道是不是喝了太多年的塑化劑,連膽子也都變小顆了。

最近104人力銀行拍了一個廣告:

廣告中的那句台詞「記住你青春無畏的樣子」,整個打到我的點。

可能因為讀的是醫學院的關係,同學大多是去醫院或學校就職,一路上其實沒太多的同學或朋友是可以一起討論。加上我這人又很愛現,學到一點覺得不錯的東西就想找人講,不然會覺得整個不痛快。只可惜我喜歡的東西又通常都不是主流,就算一起工作的同事或主管也不見得有興趣,所以很多時候,我只能把它當做自己下班後的娛樂。

又也許因為工作、小朋友的關係,桌上的書越堆越高,常常覺得怎麼會弄得這麼累,好幾度認真的在考慮也許應該去找家傳統產業的IT部門窩著養老就好。

雖然有了家庭、小孩後,做事情的確是得小心謹慎些,不過這個廣告提醒了我,以前那個熱血年輕人好像還活著,而似乎還沒想這麼早就讓我過爽爽。

感謝活在這個社群媒體(Facebook、twitter、plurk)盛行的時代,加上近來越來越熱絡的實體聚會,以前只能在網路上或書本上遠觀的高手,慢慢的也有機會跟他們交流心得。學習的路上有伴,而且還是高手的伴,的確會讓這條路走得更久一些。

前兩天在網路上看到轉載的影片,主題是「偉大的領導者如何激勵行為」:

看了眼淚差點掉下來,真的是太感動了,講者講了好多我需要改進的地方。我雖然相信「相信」這件事可以化為力量,只可惜很容易幾分鐘熱度就退燒了。

曾經有人問我應該怎麼學好程式? 我簡單的說:「就多練習吧,除非你是天才,不然這一條路沒有捷徑」,大部份的你我都是從不會開始。

不要花太多時間來評估「應該學哪種程式語言最好」,這世上沒有什麼是”最好的”程式語言。只要肯花時間開始學就會有收獲、有進步。我在第五次的AS讀書會的最後一張投影片寫著:

“只要你開始動手做,你一定會變強“

不要想太多,如同某個運動品牌的口號:「Just Do It!」,去做就是了。

雖然目前離我設定的目標還很遠,不過我是這樣走過來的。我不是天才,我可以,我相信大家應該也都可以。謹以此文提醒自己,也希望自己能永遠記得當年開始寫程式的初衷。

共勉之!

第五回AS讀書會之「嗯! 設計API我也會」

image

第五回的AS讀書會,輪到小的來給大家分享自己在過去工作上關於寫程式的一些入門心得。這次有機會可以跟新德老師一起同台,真的是太榮幸了。

以下是影片:

第一段:

第二段:

第三段:

心得

  1. 下次我也要來live demo!!
  2. 還得在修一下講話時候過多的贅字還有講話太快的毛病
  3. 是真的該減肥了.. orz

感謝來參加的大家,也感謝超高效率的攝影師健雄哥的熱情贊助,一個晚上就把影片處理好了! 投影片內容如果有哪邊觀念上是有錯的,還請前輩先進們不吝指教。

咱們下回見!

Ruby裡的方法呼叫

Ruby裡的方法呼叫雖然還滿直覺的,不過偶爾可能會因為位置、角色的不同而會有不同的結果。

雙胞胎?

直接來一段程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
class ObjA
  def func
      puts "this is method func"
  end

  def func
      puts "this is a later func"
  end
end

obj = ObjA.new
obj.func # 猜猜這裡會是什麼?

在 Ruby 裡,如果在同一個 scope 底下定義了兩個同名的 method 並不會發生錯誤,但先定義的 method 會被後面定義的給蓋掉,所以執行這段程式的話:

> ruby test.rb
this is a later func

如果你有打開 Ruby 的警告模式選項(-w),在執行的時候就會出現警告訊息:

> ruby -w test.rb
test.rb:7: warning: method redefined; discarding old func
test.rb:3: warning: previous definition of func was here
this is a later func

血脈相連

再來我們看一下在類別裡的方法呼叫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ObjA
  def func
      puts "this is ObjA"
  end
end

class ObjB < ObjA
  def func
      puts "this is ObjB"
      super
  end
end

obj = ObjB.new
obj.func # 猜猜這裡會是什麼?

你在 ObjB 類別裡的看到的那個 super,它會呼叫跟它血緣最近的父類別的同名method。它會延著繼承一直往上找,如果一直找都找不到同名的method的話,則會跳出錯誤訊息:

NoMethodError: super: no superclass method ‘func’

上面這段程式的執行結果:

> ruby test.rb
this is ObjB
this is ObjA
Who’s your daddy?

Ruby 的 OOP 是單一繼承的,藉由引入了 module 的 Mixin 概念,可以讓你有用到多重繼承的好處,又不擔心多重繼承的問題(例如鑽石繼承問題)

來看程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module ModA
  def mod_method
      puts "this is mod_method in ModA"
  end

  def func
      puts "this is ModA"
  end
end

module ModB
  def mod_method
      puts "this is mod_method in ModB"
  end

  def func
      puts "this is ModB"
  end
end

class ObjA
  def func
      puts "this is ObjA"
  end
end

class ObjB < ObjA
  include ModA
  include ModB

  def func
      puts "this is ObjB"
      super
      mod_method
  end
end

obj = ObjB.new
obj.func # 猜猜這裡會是什麼?

在往下看之前,可以先想一下最後一行的 obj.func 會印出什麼答案?

在 Ruby 裡,如果在類別裡有引進了 module,而 module 裡剛好有跟類別定義了同名的 method 的話,會以類別裡定義的方法為主。我們來看一下執行的結果:

> ruby test.rb
this is ObjB
this is ModB
this is mod_method in ModB

第一行的 ”this is ObjB” 沒問題,確實是呼叫 ObjB 的 func,但第二行為什麼是 ModB 而不是 ”this is ObjA”? 不是會呼叫離它最近的父類別同名 method 嗎?

沒錯,的確是呼叫離它最近的父類別同名 method,但被 module 給 mixin 之後,繼承的族譜有稍微變了。我們直接來看一下這行:

1
p ObjB.ancestors # [ObjB, ModB, ModA, ObjA, Object, Kernel]

你會發現 ObjB 的老爸本來應該是 ObjA,但透過 mixin 之後卻變成 ModB、ModA、ObjA,再來才是 Object(如果在 Ruby 1.9 版本之後,上面還有個 BasicObject)。至於這邊的 Kernel 是什麼? 它也是個 mixin 到 Object 裡的一個 module 而已。

所以這個地方的 super 會呼叫離它最近的 func,也就是 ModB 的 func。

那假設我們引入了兩個剛好有定義同名 method,這樣一來又要呼叫誰的? 規則其實也滿簡單的,跟 method 定義有點像,就是比較晚 include 裡來的,會蓋掉前面 include 的模組方法。所以在這邊的第三行會是 ”this is mod_method in ModB”

快快樂樂來寫 code

接下來如果時間允許的話,預計會來把「快快樂樂學Ruby」系列給補完,希望可以在大家在學習 Ruby 的時候,帶來一些些的幫助。

若內容有錯誤或觀念不正確,再請不吝告知,感謝!

Ruby 1.8 v.s. 1.9

image

其實Ruby 1.9已經推出N年,也算有點年紀的東西了。我想Ruby 1.8跟1.9的版本差別,對一般的developer來說,比較關心的點也許是這兩個版本在語法上有沒有哪邊不同? 是不是在1.8版寫的程式到1.9版都能完全不出問題? 讓我們繼續看下去…

Gems變內建的了

Rubygems在1.8版需要另外安裝,但在1.9安裝的時候也會一併裝進去,另外在1.8版可能偶爾會需要來一行:

1
require "rubygems"

這個在1.9也可以不需要了。

載入的路徑”有一點”不

在1.9版,預設的載入路徑把”.”(小數點一點,也就是目前的同錄)給拿掉了,所以在require的時候可能要注意一下。

支援Unicode

因為1.9起開始支援unicode,所以tr跟Regexp也都開始看得懂unicode了

老祖宗變了

直接來段程式碼:

1
2
3
4
5
6
7
8
class Test
end

# ver 1.8
p Test.ancestors # [Test, Object, Kernel]

# ver 1.9
p Test.ancestors # [Test, Object, Kernel, BasicObject]

Ruby 1.9版在Object上面還多了個BasicObject:

1
2
3
4
5
6
# ver 1.8
p Object.superclass # nil

# ver 1.9
p Object.superclass # BasicObject
p BasicObject.superclass # nil

BasicObject變成 1.9版的最上層類別了。

字串處理

1
2
3
4
5
6
7
# ver 1.8
p "hello"[1]   # 得到101
p ?a           # 得到97

# ver 1.9
p "hello"[1]   # 得到"e"
p ?a           # 得到"a"

另外,String#each這個方法在1.9已經被拿掉囉,請改用String#each_byteString#each_char以及String#each_line

陣列

1
2
3
4
5
# ver 1.8
p [1, 2, 3, 4, 5].to_s  # 得到"12345"

# ver 1.9
p [1, 2, 3, 4, 5].to_s  # 得到"[1, 2, 3, 4, 5]"

印出來的結果不一樣了

Hash

1
2
3
4
5
6
7
me = {:name => 'eddie', :age => 18, :gender => 1}

# ver 1.8
p me # 得到 {:age=>18, :gender=>1, :name=>"eddie"}

# ver 1.9
p me # 得到 {:name=>"eddie", :age=>18, :gender=>1}

在1.9版的hash,不管是新建立或是後來再附加上去,它都變得有”順序”了

另外1.9版有支援新的寫法,上面這段就可以改寫成:

1
me = {name: "eddie", age: 18, gender: 1}

它會很聰明的自動把key轉成symbol。在Rails裡常用到的redirect_to,原本這樣寫:

1
redirect_to :action => index

也可以改寫成:

1
redirect_to action: index

Block

看一下這段程式碼:

1
2
3
4
5
6
i = 0
p i
(1..5).each do |i|
  # do something
end
p i

在1.8版本,最後一行會印出數字5,但在1.9則是印出數字0,block裡的區域變數不會影響到外部的變數了。

Method

使用methods方法可以印出該類別或物件的方法:

1
2
3
# ver 1.8
p String.methods.sort
["<", "<=", "<=>", "==", "===", "=~", ">", ">=", "__id__", "__send__", "allocate", "ancestors", "autoload", "autoload?", "class", "class_eval", "class_exec", "class_variable_defined?", "class_variables", "clone", "const_defined?", "const_get", "const_missing", "const_set", "constants", "display", "dup", "enum_for", "eql?", "equal?", "extend", "freeze", "frozen?", "hash", "id", "include?", "included_modules", "inspect", "instance_eval", "instance_exec", "instance_method", "instance_methods", "instance_of?", "instance_variable_defined?", "instance_variable_get", "instance_variable_set", "instance_variables", "is_a?", "kind_of?", "method", "method_defined?", "methods", "module_eval", "module_exec", "name", "new", "nil?", "object_id", "private_class_method", "private_instance_methods", "private_method_defined?", "private_methods", "protected_instance_methods", "protected_method_defined?", "protected_methods", "public_class_method", "public_instance_methods", "public_method_defined?", "public_methods", "respond_to?", "send", "singleton_methods", "superclass", "taint", "tainted?", "tap", "to_a", "to_enum", "to_s", "type", "untaint"]

回傳的是方法的字串陣列。

1
2
3
p String.methods.sort
# ver 1.9
[:!, :!=, :!~, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :allocate, :ancestors, :autoload, :autoload?, :class, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :clone, :const_defined?, :const_get, :const_missing, :const_set, :constants, :define_singleton_method, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :include?, :included_modules, :initialize_clone, :initialize_dup, :inspect, :instance_eval, :instance_exec, :instance_method, :instance_methods, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :kind_of?, :method, :method_defined?, :methods, :module_eval, :module_exec, :name, :new, :nil?, :object_id, :private_class_method, :private_instance_methods, :private_method_defined?, :private_methods, :protected_instance_methods, :protected_method_defined?, :protected_methods, :public_class_method, :public_instance_method, :public_instance_methods, :public_method, :public_method_defined?, :public_methods, :public_send, :remove_class_variable, :respond_to?, :respond_to_missing?, :send, :singleton_class, :singleton_methods, :superclass, :taint, :tainted?, :tap, :to_enum, :to_s, :trust, :try_convert, :untaint, :untrust, :untrusted?]

在1.9變成回傳symbol的陣列了。那會有什麼影響? 如果你有寫到這樣的程式碼來判斷某個類別是否有實作某個方法的話:

1
p String.methods.include? "to_s"

在1.8會是true,但在1.9就會是false了。所以如果你要做這樣的判斷,請使用respond_to?method_defined?

1
2
p String.respond_to? "to_s"
p String.method_defined? "to_s"

Lambda

1
2
3
4
5
6
7
# ver 1.8
my_calc = lambda { |a, b| a * b }
p my_calc.call(10, 20)

# ver 1.9
my_calc2 = -> a, b { a * b }
p my_calc2.(10, 20)

在1.9版的lambda可以用上面這個方法來寫,而且call方法也可以省略。

預設參數

1
2
3
4
5
6
7
def hello(a, b = 10, c)
  p a, b, c
end

p hello(1)        # ArgumentError
p hello(1, 2)     # [1, 10, 2]
p hello(1, 2, 3)  # [1, 2, 3]

在1.9版在參數個數不夠的時候,可以直接填給沒有預設參數的部份。

結論

其實這兩個版本的差異當然不只這樣,我僅就我個人比較常用到的部份做個筆記,順便也提醒自己。以上內容若有任何錯誤再請讓我知道,感謝。

參考資料: