昨天提到的引數有好幾種,今天要來介紹Ruby 常用的block 引數:『區塊引數』。
區塊是什麼呢?本篇文章只有先撥開一點點它的包裝,更深入的內容還有待之後分享!
這次鐵人賽的主題就是使用區塊的一例子:
10萬.times { puts "為什麼?" }
.times
是Integer的實體方法,怪了,我們昨天說過,方法的後面接的應該是個( )
,( )
的裡面會放入引數,但這個.times
方法後面卻接著長得很像雜湊(Hash)
的東西,這到底是啥?
好的,先不要把這個跟雜湊搞混了,我們以前在Ruby女孩(11)中提到的雜湊,雜湊是長這樣的:
{:name => "Annie",:age => 99}
或
{name: "Annie", age: 99}
很明顯你在雜湊中會看到一對一對的鍵(Key)與值(Value),與Numeric、String與Array一樣都是Ruby中的資料型別。但今天所要認識的『區塊(block)』,它並不是另一種資料型別,它是迭代器的基礎,我們接下來會好好認識它是怎麼運作,而方法要如何調用它?
{ }
或是do
和end
當作區塊的起始與終止。{
或do
,一定要跟方法名稱放在同一列。{}
;若超過一行,則使用do
/end
。1.upto(10) { |x| puts x }
或
1.upto(10) do |x|
puts x
end
1.upto(10) {|x| puts x} #正常執行
1.upto 10 do |x| puts x end #正常執行
1.upto 10 {|x| puts x} #SyntaxError
區塊會找緊接著它的方法試圖傳進去,第三種會出現SyntaxError,就是因為它以為緊跟著它的方法是10,才會噴錯!所以若想省略方法的圓括號,請改以do
/end
撰寫。不然就不要省略!!
test.each { |x,y,z| puts "#{x}、#{y}、#{z}" }
{
或do
寫在同一行。OK,看完區塊的基本規則,我們來了解一下該如何在方法的引數中傳入區塊。
由於區塊是不具名稱的,他們的調用是要前綴一個『&』符號,而且規定一定要寫在引數的最後一個!實際使用的方式如下:
def test(a,b,*c,&d)
puts "a=#{a}"
puts "b=#{b}"
puts "c=#{c}"
d.call(5)
end
test(1,2,3,4,5){|n| n.times{puts "ruby"}}
a=1
b=2
c=[3, 4, 5]
ruby
ruby
ruby
ruby
ruby
你可以注意到,我們在方法後面直接丟入了一個區塊作為&d
的引數,並且在方法中,用.call
來給予區塊本身的區塊參數!那.call
這個方法是誰的方法呢?我們可以用這個方法看看區塊到底是誰?
def who_am_i(&block)
"我其實是#{block.class}"
end
who_am_i{}
=> "我其實是Proc"
好像解謎一樣,一層一層把區塊的秘密掀出來XD 原來區塊是Proc
,Proc
和Lambda
是另一組容易被搞混的詞,這個部分我得好好吸收一下才知道怎麼寫出來不會誤導大家!有待明天揭曉XD
最後補充一個書上目前沒看到的傳遞引數的方式:
def sum(a, *b, **c, &d)
puts "a=#{a}"
puts "b=#{b}"
puts "c=#{c}"
d.call(100)
end
sum(1,2,3,4,5,x:6,y:7) { |x| puts x }
a=1
b=[2, 3, 4, 5]
c={:x=>6, :y=>7}
100
有看見上面的c前綴的是**
,與*
不同的是,**
可以傳進雜湊的值,也因此你才可以看到上面puts c
之後的結果!
28天!
“Decide that you want it more than you are afraid of it.”
雖然讀的內容越來越深,但想學的心還是大於害怕!加油加油!