2016-10-28 49 views
0

我讀這個關於Ruby PROCS:Ruby塊和procs。使用Proc時,你不需要指定第二個參數嗎?

class Monkey 

    # Monkey.tell_ape { "ook!" } 
    # ape: ook! 
    # => nil 
    def self.tell_ape 
    tell("ape", &Proc.new) 
    end 

    def self.tell(name) 
    puts "#{name}: #{yield}" 
    end 
end 

在該示例以上...的塊被傳遞給.tell_apeProc.new在塊轉換爲PROC正確?但是... .tell方法不需要在其方法簽名中接受&block參數嗎?我們正在將Proc作爲參數傳遞給.tell方法嗎?如果是的話...... .tell方法不需要第二個參數嗎?

回答

2

所有方法始終正好一個可選的塊參數:

puts('Hello') { I.can.write.whatever.i.want.here.because.the.block.is.never.ran } 
# Hello 

def foo; end 
foo { same.here } 

塊的整點是,他們是語法和語義輕便,其中一種實現方式是它們是匿名的:

def bar; yield if block_given? end 
# Note how I didn't need to say where to yield to and what block to check since 
# there can only ever be at most one anyway. 

bar { puts 'Hello' } 
# Hello 

他們也不是對象。

但是,如果它沒有名稱,甚至不是一個對象,那麼如何引用它?嗯,這就是&參數進來:他們告訴Ruby來塊轉換成適當的Proc對象,並將其綁定到一個參數:

def baz(&blk) p blk end 
baz { again.we.are.not.calling.the.block } 
# #<Proc:[email protected](pry):42> 
# ^^^^^^^ Debugging representation of a Proc object 

Proc■找一個call方法,執行它們(有也是一塊調用call語法糖):

def quux(grault, &blk) 
    blk.(grault) 
    yield grault 
end 

quux('Hello') {|garply| puts garply } 
# Hello 
# Hello 
1

當您有一個接收塊的方法時,yield關鍵字將執行該塊,您不必將其顯式作爲參數傳遞。

def foo 
yield 1 
end 

等同於:

def foo(&block) 
    block.call(1) 
end 
+0

它不完全等同,因爲第一個版本不需要塊重新指明分數作爲'Proc',實際上所有現有的Ruby實現將*不*分配第一種情況下的Proc對象。 –

相關問題