多值傳入與取得( Array的傳值展開與包裝 , *argv )


#1

如題

option = [:a,:b,:c]
A.new(*option)

請問這個星號是怎麼來的呢?
題目來自於
http://railscasts.com/episodes/272-markdown-with-redcarpet

def markdown(text)
  options = [:hard_wrap, :filter_html, :autolink, :no_intraemphasis, :fenced_code, :gh_blockcode]
  syntax_highlighter(Redcarpet.new(text, *options).to_html).html_safe
end

#2

hmm … 發覺我之前沒有寫方便的Array對傳入值的展開法,不過我教學內都有講就是了,這邊順便寫詳細些,並修改主題:多值傳入與取得( Array的傳值展開與包裝 )

require 'pp'
def temp(a,b,c)
   pp [a,b,c]
end

請問 Array 如何傳入?傳統很麻煩,類似

a = 1 ; b = 2 ; c = 3
temp(a,b,c)
#=> [1, 2, 3]

而你有更簡單方便的選擇

input = [1,2,3]
temp(*input)
temp(*[1,2,3])
temp(*[1,2],3)
temp(1,2,*[3])
#=> [1,2,3] #上面全都是

所以 * + Array = 把 Array 解開,然後當傳入值傳入,而另外一個方面,method 取得也有這東西

def temp2(a,b,*argv)
  pp [a,b,argv]
end

temp2(1,2,3,4,5,6,7,8,9)
#=> [1, 2, [3, 4, 5, 6, 7, 8, 9]]

所以多的就會變成 argv 那個鬼東西,而 argv 是統稱的變數名,你可以自己改,其餘的這邊有寫

再來就是 = 這個鬼東西,如果用,分隔,會有不同的效果,類似

a , b = 1 , 2
#=> a = 1 , b = 2
a , b = [2 , 4]
#=> a = 2 , b = 3
(a , b)=([3 , 4])
#=> a = 3 , b = 4

a = 1,2,3
#=> a = [1, 2, 3]
a , b = 1 , 2 , 3
#=> a = 1 , b = 2
a , b = 1
#=> a = 1 , b = nil

這邊解釋一下, = 在 Ruby 內是 method,所以加上( )再正常不過的,而有 , 分隔傳入的話,會自動變Array輸入,另外一方面,如果前面也有 , 做分隔的話,則把後面的 Array 再解開,所以Ruby最簡單的 swap 方式會變成

a = 9 ; b = 8
a , b = b , a
#=> a = 8 , b = 9

所以順序是,b , a => [ b , a ],然後餵到前面去,再用上面 method 的 * 的方式解開,然後餵給 a , b

anyway 下次看到 * 在某個 array 變數之前,就當作解開即可,以上