[心得] Symbol.to_proc 之應用
== 緣起
剛剛看到這篇 http://snippets.dzone.com:80/posts/show/4000 :
bad_dirs = Directory.find(:all, :conditions => ["description IS NULL"],
:order => "created_at").collect(&:created_at)
才知道可以像黃色的部份那樣子寫。不過我在 irb 裡試卻試不出來,
跟學弟討論也沒有結果,不過他幫我找到這篇文章:
http://www.sitepoint.com/blogs/2006/06/19/insta-block-with-symbolto_proc/
== Symbol.to_proc
簡單說,就是 Rails 從 0.14.4 之後,幫 Symbol 加上了 to_proc 這個 method,
讓你可以把
articles.collect { |a| a.title }
寫成
articles.collect(&:title)
相關的文件說明在 http://api.rubyonrails.org/classes/Symbol.html 。
到這邊為止,我們知道怎麼把 Symobl 轉成 Proc 物件了,
但是 & 跟 to_proc 中間好像還少了一些連結。
== & 與 to_proc
本來,我知道 functions / methods 在處理 block 時,可以用 & 來處理:
( block 就是一種 Proc 物件 )
def func_need_a_block(&blk) # 接受一個 block 並取名為 blk
....
end
func_need_a_block { } # 呼叫 function 時傳遞一個 block
甚至是用來再次傳遞 block (Proc 物件):
def func_pass_block(&blk)
func_need_a_block(&blk) # 把 blk 當作 block 而非一般參數來傳遞
end
如果你傳遞的 block 不是一個 Proc 物件呢?像是底下這樣:
class C
......
end
c = C.new
func_need_a_block(&c)
遇到這種狀況,Ruby 會先試著去呼叫 c.to_proc,嘗試得到一個 Proc 物件,
如果成功,就把這個物件丟給 func_need_a_block。
但是 & 的作用只在標明這個變數是要當作 block 傳遞,
而不等於呼叫 to_proc,也就是說像下面這樣寫是不行的:
p = &obj_with_to_proc # Error!!
以上是對 Symbol.to_proc, &, to_ptoc 的簡單整理。
== 更多 to_proc 的應用
有了上面所講的 Symbol.to_proc,我們可以把常見的 mapping 動作:
>> list = ['1', '2', '3']
=> ["1", "2", "3"]
>> list.map {|item| item.to_i}
=> [1, 2, 3]
簡化成:
>> list.map &to_i
=> [1, 2, 3]
但是有人覺得這樣還是要打太多字了,他希望弄成這樣:
>> list.to_is
=> [1, 2, 3]
想知道怎麼作嗎?看這篇文章吧:
http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 218.166.111.187
Ruby 近期熱門文章
PTT數位生活區 即時熱門文章