如何从外部获得给定lambda的参数值,而不明确返回其“绑定”?
我希望能够运行lambda并获取其参数值(a
和b
的值下面的值)。
我可以通过显式使lambda返回绑定
,然后从此绑定中获取值:
fun = lambda { |a, b = Time.now| binding }
fun_binding = fun.call(123)
puts "A is #{fun_binding.local_variable_get(:a)} and B is #{fun_binding.local_variable_get(:b)}"
# Outputs e.g.: A is 123 and B is 2022-04-29 20:14:07 +0200
是否有可能在lambda主体内部运行任何代码而获得这些值?即我可以做
fun = lambda { |a, b = Time.now| }
fun.call(123)
,仍然可以从lambda外部以某种方式获得a
a b 值吗?
(提供上下文 - 我问是因为我对于在此阶段自动分配的IVAR/读者实例化对象。
I want to be able to run a lambda and get at its argument values (the values of a
and b
below).
I can achieve this by explicitly having the lambda return a binding
, and then getting the values out of this binding:
fun = lambda { |a, b = Time.now| binding }
fun_binding = fun.call(123)
puts "A is #{fun_binding.local_variable_get(:a)} and B is #{fun_binding.local_variable_get(:b)}"
# Outputs e.g.: A is 123 and B is 2022-04-29 20:14:07 +0200
Is it possible to get these values without running any code inside the lambda body? I.e. could I do
fun = lambda { |a, b = Time.now| }
fun.call(123)
and still get the a
and b
values somehow from outside the lambda?
(To provide context – I'm asking because I've experimented with this as a shortcut syntax for instantiating objects with ivars/readers automatically assigned. At this stage I'm more curious about what's possible than what is advisable – so I invite any solutions, advisable or not…)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定这是多么可取,但是您可以使用
TracePoint
与类:B_CALL
事件要抓住lambda的绑定:这不是一个完美的解决方案,如果一个参数默认值之一输入一个块,则将失败(由于在
:b_call
事件之前对lambda发射默认值是在评估默认值的),但是可以在跟踪点处理程序中使用一些其他过滤修复。I'm not sure how advisable this is, but you can use the
TracePoint
class with the:b_call
event to grab the lambda's binding:This is not a perfect solution and will fail if one of the argument default values enters a block on it's own (since the default values are evaluated before the
:b_call
event is fired for the lambda), but that could be fixed with some additional filtering inside the TracePoint handler.