如何从外部获取给定 lambda 的参数值,而不显式返回其“绑定”?
How can I get argument values for a given lambda from the outside, without explicitly returning its `binding`?
我希望能够 运行 lambda 并获取其参数值(下面 a
和 b
的值)。
我可以通过明确地让 lambda return 成为 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
是否可以在没有 运行lambda 体内任何代码的情况下获得这些值? IE。我能做吗
fun = lambda { |a, b = Time.now| }
fun.call(123)
并且仍然以某种方式从 lambda 外部获取 a
和 b
值?
(提供上下文——我问是因为我已经 experimented 将此作为实例化对象的快捷语法 ivars/readers 自动分配。在这个阶段我更好奇什么是可能的而不是什么是可取的——所以我邀请任何解决方案,无论是否明智……)
我不确定这是否明智,但您可以使用 TracePoint
class 和 :b_call
事件来获取 lambda 的绑定:
fun = lambda { |a, b = Time.now| }
fun_binding = nil
TracePoint.trace(:b_call) do |tp|
fun_binding = tp.binding
tp.disable
end
fun.call(123)
puts "A is #{fun_binding.local_variable_get(:a)} and B is #{fun_binding.local_variable_get(:b)}"
这不是一个完美的解决方案,如果其中一个参数默认值自己进入一个块,将会失败(因为默认值是在为 lambda 触发 :b_call
事件之前评估的),但是这可以通过在 TracePoint 处理程序中进行一些额外的过滤来解决。
我希望能够 运行 lambda 并获取其参数值(下面 a
和 b
的值)。
我可以通过明确地让 lambda return 成为 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
是否可以在没有 运行lambda 体内任何代码的情况下获得这些值? IE。我能做吗
fun = lambda { |a, b = Time.now| }
fun.call(123)
并且仍然以某种方式从 lambda 外部获取 a
和 b
值?
(提供上下文——我问是因为我已经 experimented 将此作为实例化对象的快捷语法 ivars/readers 自动分配。在这个阶段我更好奇什么是可能的而不是什么是可取的——所以我邀请任何解决方案,无论是否明智……)
我不确定这是否明智,但您可以使用 TracePoint
class 和 :b_call
事件来获取 lambda 的绑定:
fun = lambda { |a, b = Time.now| }
fun_binding = nil
TracePoint.trace(:b_call) do |tp|
fun_binding = tp.binding
tp.disable
end
fun.call(123)
puts "A is #{fun_binding.local_variable_get(:a)} and B is #{fun_binding.local_variable_get(:b)}"
这不是一个完美的解决方案,如果其中一个参数默认值自己进入一个块,将会失败(因为默认值是在为 lambda 触发 :b_call
事件之前评估的),但是这可以通过在 TracePoint 处理程序中进行一些额外的过滤来解决。