iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 5
0
自我挑戰組

Ruby and Rails 的二三事系列 第 5

Ruby on Rails 的二三事 - Day05 稍微介紹一下:Method 和 Block

Method

前面一直提到方法,那麼到底在Ruby裡,方法(Method)是怎麼被定義的呢?

下面是,在Ruby裡,我們定義方法和呼叫方法的樣子:

def 方法名稱(參數個數隨意)

end
  • 呼叫方法的時候,() 是可以省略的:
def say_hello_to(someone)
  puts "Hi, #{someone}"
end

 say_hello_to("DinDin") # "Hi, DinDin"
 say_hello_to "LaLa"    # "Hi, LaLa"

Method的一些觀念:

  • 在定義方法的時後,可以先給他預設值:
def say_hi_to(some = "Vegeta")
  puts " I'm #{some}"
end

say_hi_to()       # "I'm Vegeta"
say_hi_to("Goku") # "I'm Goku"

  • ?和!也可以是方法的一部份

方法名稱後面如果接上? ,通常我們預期他會回傳true or false;
當然你也可以惡搞:

def can_fly?(age = 10)
    if (age <= 10)
      #true
      return "I can fly, cause I'm #{age}." 
    else
      #false
      return "Oops,you're #{age}, that's why you can't fly."
    end
end

p can_fly?
=> "I can fly, cause I'm 10." 
p can_fly?(20)
=> "Oops,you're 20, that's why you can't fly."

  • Method後面接 ! ,表示會帶來副作用

這邊我們用陣列的sort 和sort! 方法來做示範:

  list = [3, 2, 1, 5]
  p list.sort        # [1, 2, 3, 5]
  p list             # [3, 2, 1, 5]  
  p list.sort!       # [1, 2, 3, 5]
  p list             # [1, 2, 3, 5]

有看到嗎? 當你對list使用了 sort! 方法, list就回不去了...
就像變了心的女友一樣(淚目~)


Block

Block 不是物件
Block 不是參數

Ruby裡大部分的東西都是物件, 而Block就是少數的例外。
其實在前面的部分Block 就已經出現過了:

a.each do |i|
 b << i if i % 2 == 1
end

 a.select {|i| i % 2 == 1}

上面在 each "方法後面" 的 do...end 和
select "方法後面" 的 { },就是所謂的Block。

會強調"方法後面"是因為:

Block 是不能單獨存在的。
Block 只是附加在方法後面,等著被呼叫的一段程式碼。

   { puts "這樣會出錯!!"}
   
   do
      puts "安捏馬港款"
   end

Block的一些觀念:

關於block的觀念,個人覺得看code最有感,所以...
廢話不多說 ,來看code吧! :)

  • Block 需要透過 yield 來呼叫
def say_hello
  puts %Q(say hello "method")
  yield
  puts %Q(back to say hello "method")
end

say_hello {
  puts %Q(say hello "block" with yield)
}
# say hello "method"
# say hello "block" with yield
# back to say hello "method"

如果沒有yield,寫在Block裡面的東西,是不會有反應的:

def meow
  puts "霹靂!霹靂!霹靂貓!!"
end
meow {
  puts "You can't see me"
}

#"霹靂!霹靂!霹靂貓!!"

  • yield 是可以傳遞參數的
def way_hi4_din
  yield "什麼","什麼"
end

way_hi4_din { |n, m|
  puts %Q(婆婆,我要#{n}你打#{n},這才是餵~)
  puts %Q(不對,妳要#{m}我打#{m},這叫做盯~)
}

# 婆婆,我要什麼你打什麼,這才是餵~
# 不對,妳要什麼我打什麼,這叫做盯~

這麼生活化的例子,應該不需要我多做解釋了吧?

  • block 會自動回傳最後的結果
def test_pregnancy
  if yield ("||")
    puts %Q(恭喜老爺!賀喜夫人!)
  else
    puts %Q(換個姿勢,再來一次!)
  end
end

test_pregnancy {|result|
  result == "||"
}

# 恭喜老爺!賀喜夫人!

下面這段程式碼是用來展示,參數傳遞的過程:

def im_from(place)
  puts "params passed from method im_from"
  yield place
  puts "leaving im_from"
end

im_from("Namek") { |place|
  puts "params pass in to block "
  puts %Q(I'm from #{place}.)
  puts "prepare go back to method "
}

# params passed from method im_from
# params pass in to block
# I'm from Namek.
# prepare go back to method
# leaving im_from

Proc

但是其實,在Ruby裡面,還是有方法可以將Block物件化的;
那就是Proc,用起來的手感大概是像這樣:

  shoot = Proc.new {|name| p "#{name}  Shooooot!!!"}

  shoot["Neo Armstrong Cyclone Jet Armstrong Cannon"]
  shoot.("Neo Armstrong Cyclone Jet Armstrong Cannon")
  shoot.===("Neo Armstrong Cyclone Jet Armstrong Cannon")

  #上面三種呼叫方式,都會得到下面的結果
  "Neo Armstrong Cyclone Jet Armstrong Cannon  Shooooot!!!"

嗯?又有奇怪的東西混進程式碼了嗎?
大概是我太累產生的錯覺吧...

鐵人賽,我們明天再會!


上一篇
Ruby and Rails 的二三事 Day04 Symbol (符號)和 String(字串) 的差別
下一篇
Ruby and Rails 的二三事 - Day06 Class(類別) 和 Module(模組) 的不同
系列文
Ruby and Rails 的二三事19
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言