ruby - Ruby 方法可以访问隐式块参数吗?
问题描述
传递给 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
Proc::new
曾经有一个未记录的技巧,实际上是在 MRI 中实现的一个意想不到的副作用:Proc::new
没有检查您是否通过了一个块,它只是假设您通过了一个块并将第一个块从顶部移开内部虚拟机堆栈。因此,如果您没有将块传递给Proc::new
,它实际上最终会Proc
为传递给该方法的隐式块创建一个(因为它恰好位于堆栈顶部)。
但是,这永远不能移植,永远不能保证,永远不会在所有 Ruby 实现中工作,并且 AFAIK 不再在 YARV 中工作。
推荐阅读
- java - 如果在 JAX-RS 资源中使用单例 javax.ws.rs.client.Client 线程安全吗?
- php - 如何将关联数组与索引数组合并
- clang - Clang 使用 fuzzer 参数显示编译器错误
- node.js - 编辑组件 html 时 Angular CLI 不会重新加载?
- algorithm - 无法计算以下算法的时间复杂度
- python - 最后一行代码是什么意思,x1[ x1[:,1]>3 ]
- c# - 如何在 C# 中正确处理第三方对象(TelegramBotClient)
- excel - 合并重复记录,然后使用 vlookup 从另一张表中提取数据
- ios - ViewControllers 之间的延迟自定义转换
- java - 将用户输入转换为字符串,遇到多个字母的问题