Ruby 學習筆記-區塊(Block)

Block 是什麼?

是一段不會被主動執行的程式碼,無法單獨存活

    5.times do |x|
        puts i
    end

    5.times { |x|
        puts i
    }

從上述例子中的do...end以及{}都是一個 Block

Block 使用

    在方法後使用可以用yield
    def say
        puts "hi"
        yield        #需要用yield把控制權暫時讓給say這個Block,如果沒有的話下方的say{}不會執行
        puts "hello"
    end

    say{
        puts "welcome"
    }

    # hi
    # welcome
    #hello

還可以把值讓出去

     def say
        puts "hi"
        yield 3        #可以在yield放值,把值讓給下方的Block
        puts "hello"
    end

    say{ |x|           #可以接收上方,方法的值
        puts x
    }
    # 3

Block 會自動回傳值

     def say
        if yield (3)    #1.讓給下方Block
            puts "yes"  #4.接收下方Block的回傳值,來判斷是否符合
        else
            puts "no"
        end
    end

    say{ |x|           #2.接受上方方法
        x == 3         #3.判斷讓出來的值是否有等於3
    }
    # yes

Block 不使用 return

Block 不是參數

如何確認方法讓出去是否有 Block

    def say
        if block_given?  #確認是否有block
            yield
        end
    end

   1. say          # 空白
   2. say{
       puts "hi"   # hi
     }

兩種 Block 的差異

Block 物件化:被物件化後,可單獨執行

  1. 使用 Proc
    say = Proc.new {|x| x + 5} #包裝後的程式碼區塊

    #呼叫Proc有以下的方式,結果都一樣
    p say.call(3)
    p say[3]
    p say.(3)
    p say.===(3)               #3+5=8
  1. 使用 lambda
    say = lambda {|x| x + 5} #包裝後的程式碼區塊

    #呼叫lambda有以下的方式,結果都一樣
    p say.call(3)
    p say[3]
    p say.(3)
    p say.===(3)               #3+5=8
  1. 使用箭頭 ->

    say = -> (x) { x + 5} #包裝後的程式碼區塊

    #呼叫箭頭有以下的方式,結果都一樣
    p say.call(3)
    p say[3]
    p say.(3)
    p say.===(3)               #3+5=8

Proc 與 lambda 的差異

say_proc = Proc.new {|x| x + 5}
say_lambda = lambda {|x| x + 5}
p say_proc .call(1,2,3) #正常執行只帶第一個引數,印出6
p say_proc .call(1,2,3) #發生引數個數錯誤
comments powered by Disqus