簡體   English   中英

Ruby 方法可以訪問隱式塊參數嗎?

[英]Can a Ruby method access the implicit block argument?

傳遞給 Ruby 方法的隱式塊參數可以使用yield執行,或者可以使用block_given? . 我正在嘗試將此隱式塊傳遞給另一個方法。

這可能嗎?

(它可以訪問我要詢問的隱式塊參數。用顯式參數替換它不會削減它。)

您可以 procify 它,更重要的是給它一個名稱,以便您可以引用它,使用方法的參數列表中的& & 和一元前綴 sigil ,如下所示:

#implicit, anonymous, cannot be referenced:
def foo
  yield 23 if block_given?
end

foo {|i| puts i }
# 23

#explicit, named, can be referenced:
def bar(&blk)
  yield 23 if block_given? # still works

  blk.(42) if blk # but now it also has a name and is a `Proc`

  # since we have the block available as an object, we can inspect it
  p blk.arity, blk.parameters, blk.source_location, blk.binding

  b = blk.binding
  p b.local_variables.map {|var| [var, b.local_variable_get(var)] }.to_h
end

quux = "Hello"

bar { |a, b, c = nil, d: nil, &e| puts a }
# 23
# 42
# 2
# [[:opt, :a], [:opt, :b], [:opt, :c], [:key, :d], [:block, :e]]
# ["(irb)", 24]
# #<Binding:0x00007fb091051308>
# { :quux => "Hello" }

這是你的兩個選擇:

  • 隱式,匿名,不是 object
  • 顯式,命名, Proc

曾經有一個未記錄的技巧,實際上是在 MRI 中如何實現Proc::new的意外副作用: Proc::new沒有檢查您是否通過了一個塊,它只是假設您通過了一個塊並且會將第一個塊從內部 VM 堆棧的頂部移開。 因此,如果您沒有將塊傳遞給Proc::new ,它實際上最終會為傳遞給方法的隱式塊創建一個Proc (因為它恰好位於堆)。

但是,這從來都不是可移植的,從來沒有保證過,從來沒有在所有 Ruby 實現中工作,並且 AFAIK 不再在 YARV 中工作。

您可以通過Proc.new引用 block 參數。 從文檔:

::new只能在帶有附加塊的方法中調用,而沒有塊,在這種情況下,該塊將轉換為Proc object。

例子:

def bar
  yield * 2
end

def foo
  bar(&Proc.new)
end

foo(123)
#=> 456

請注意, Proc.new在未傳遞塊的情況下調用時會引發ArgumentError

看看這個答案 在您的情況下,它將類似於:

def outer
  wrapper = lambda { |something|
    p 'Do something crazy in this wrapper'
    yield(something)
  }
  other_method(&wrapper)
end

def other_method
  yield(5)
end

outer { |x| puts x + 3 }

有了它,你會得到:

"Do something crazy in this wrapper"
8
=> nil

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM