[英]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" }
這是你的兩個選擇:
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.