Com*_*ubh 1 ruby closures block
传递给 Ruby 方法的隐式块参数可以使用 来执行yield
,或者可以使用 来检查它的存在block_given?
。我试图将这个隐式块传递给另一个方法。
这可能吗?
(这是对我要问的隐式块参数的访问。用显式参数替换它不会削减它。)
你可以 procify 它,更重要的是给它一个名字,以便你可以引用它,&
在方法的参数列表中使用&符号一元前缀符号,如下所示:
#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" }
Run Code Online (Sandbox Code Playgroud)
这是你的两个选择:
Proc
曾经有一个未公开的技巧,它实际上Proc::new
是 MRI 中实现方式的意外副作用:Proc::new
不检查您是否通过了一个块,它只是假设您通过了一个块并将第一个块从顶部移走内部 VM 堆栈。因此,如果您没有将块传递给Proc::new
,它实际上最终会Proc
为传递给该方法的隐式块创建一个(因为它恰好位于堆栈顶部)。
但是,这从来都不是可移植的,从来没有保证过,从来没有在所有 Ruby 实现中工作过,而且 AFAIK 也不再在 YARV 中工作。
归档时间: |
|
查看次数: |
483 次 |
最近记录: |