2015-10-13 48 views
0

快速的問題,我已經碰到這個select(&:even)語法跑了幾次,我理解它,除了一件事大部分:簡單的Ruby PROC用(:)

&符號,對我來說,是什麼使得方法名稱,以及方法名稱。我不明白爲什麼需要符號語法來定義偶數。在很短的例子:

arr = [1,2,3,4,5] 
puts arr.select(&:even?) 

正確選擇並打印所有偶數但是,

arr = [1,2,3,4,5] 
puts arr.select(&even?) 

生產:

Untitled 3.rb:2:in <main>: undefined method even? for main:Object (NoMethodError)

誰能幫助我理解使用的必要性:符號?

+2

方法名稱是符號,所以引用方法':even?'。運算符'&'做兩件事:它調用方法名稱上的[Symbol#to_proc](http://ruby-doc.org/core-2.2.0/Symbol.html#method-i-to_proc)將其轉換到一個proc([Proc](http://ruby-doc.org/core-2.2.0/Proc.html)的實例),然後調用proc。如果你有'arr.select(&proc)',它只會調用proc。 –

+0

我無法解析你的句子'(&符號,對我來說)是什麼使得方法名稱,以及方法名稱。 – sawa

+0

爲什麼你會認爲它會在沒有':'的情況下工作? – sawa

回答

2

如「What does map(&:name) mean in Ruby?」中所述,&:whatever語法在proc中轉換:whatever方法並將其傳遞給調用者。

puts arr.select(&:even?) 

相當於

puts arr.select { |x| x.even? } 

之所以&:whatever作品而&whatever不,是因爲在後一種情況下Ruby的虛擬機將實際嘗試評估whatever,並將結果傳遞到&,當你真正想要的是一種懶惰評估。你想要傳遞一個方法引用/名稱爲&,而不是執行方法本身。

您遇到這個錯誤是因爲下面的代碼

puts arr.select(&even?) 

可以理解爲

  1. 執行even?
  2. 得到返回值,並把它傳遞給&
  3. ...但嘿... even?沒有定義(注意目標是隱含的)...崩潰!