ruby 疑痛點之—— yield 和 yield self

來源:互聯網
上載者:User

標籤:

yield

所有的"方法(methods)"隱式跟上一個"塊(block)"參數。

塊參數也可以明確給定,形式就是在參數前面加一個"&",比如 def fn(arg1, arg2, &block) end,其中的 &block 就是明確給定的塊參數。

塊參數的動作,可以通過調用 call() 方法執行,還可以用 yield 來執行 —— yield 其實就是一個文法糖。

所以以下幾種寫法常常是等價的:

#method receives an invisible block argumentdef foo1()    yield 1end#specify it explicitlydef foo2(&block)    yield 1end#yield is equal to block.calldef foo3(&block)    block.call(1)    end#function callfoo1 {|x| puts x}    # => 1foo2 {|x| puts x}    # => 1foo3 {|x| puts x}    # => 1

 

Proc

前面說到所有方法都可以隱式或顯式指定一個塊參數,那麼塊參數到底是什麼呢?

答案是 Proc 對象,一個具有 call 方法的對象。

Proc 對象的定義有幾種形式:

  • 直接使用 {}
  • 使用 Proc.new {}
  • 使用 proc {}
  • 使用 lambda {}
#yield is equal to block.calldef foo(&block)    puts block.class    puts block.to_s    yield 1    end#function call# Proc created using {} syntaxfoo {|x| puts x}   # => Proc# => #<Proc:[email protected](ruby):9># => 1# Proc created with the "proc" keyword. Note & syntax when calling.my_proc = proc { |n| puts n }foo(&my_proc)# => Proc# => #<Proc:[email protected](ruby):12># => 1# Proc creates with Proc.newmy_proc = Proc.new { |n| puts n }foo(&my_proc)    # => 1# => Proc# => #<Proc:[email protected](ruby):16># => 1# Proc created with the "lambda" keyword. Nearly same thing.my_proc = lambda { |n| puts n }foo(&my_proc)# => Proc# => #<Proc:[email protected](ruby):20 (lambda)># => 1

 

yield self

在一個對象中,self 表示是一個當前對象的引用。

所以,常見的 yield self if block_given? 中的 self 就和其它地方使用 self 一樣,沒什麼特殊的。

class C1    def foo(&block)        puts block.class        puts block.to_s        yield self if block_given?        yield "AAAAAAAAA"    endendclass C2    def foo(&block)        puts block.class        puts block.to_s        yield self if block_given?        yield "BBBBBBBBB"    end        def to_s        "XXXXXXXXXX"    endendc1 = C1.newc1.foo  {|x| puts x}# => Proc# => #<Proc:[email protected](ruby):23># => #<Context::C1:0x00000001c84af0># => AAAAAAAAAc2 = C2.newc2.foo  {|x| puts x}# => Proc# => #<Proc:[email protected](ruby):26># => XXXXXXXXXX# => BBBBBBBBB

 

注意事項

method 定義中 &block 參數必須在最後

# 正確樣本def foo(arg1, arg2, &block)    puts blockend#function callblock = proc {|x| puts x}foo( 1, 2, &block)                   # => #<Proc:[email protected](ruby):14>#錯誤樣本def foo(arg1, &block, arg2)     # => (ruby): syntax error    puts blockend

yield 相當於是 block.call() 方法的調用,所以參數個數也需要對應

def foo()    yield 1,2,3     # 這裡的 1 2 3 就是傳遞的參數end#function callfoo {|x| puts x}        # => 1foo {|x,y,z| puts z}    # => 3foo {|x,y,z,k| puts k}  # 為空白

 

ruby 疑痛點之—— yield 和 yield self

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.