gpt4 book ai didi

ruby - 如何从 method_missing 获取绑定(bind)?

转载 作者:数据小太阳 更新时间:2023-10-29 07:43:40 25 4
gpt4 key购买 nike

我试图找到一种方法来在 Ruby (1.8) 的 method_missing 中从调用者那里获取绑定(bind),但我似乎无法找到实现它的方法。

希望下面的代码能解释我想做什么:

class A
def some_method
x = 123
nonexistent_method
end

def method_missing(method, *args, &block)
b = caller_binding # <---- Is this possible?
eval "puts x", b
end
end

A.new.some_method
# expected output:
# 123

那么...有没有办法获得调用者的绑定(bind),或者这在 Ruby (1.8) 中是不可能的?

最佳答案

这是一个(有点脆弱的)hack:

# caller_binding.rb
TRACE_STACK = []
VERSION_OFFSET = { "1.8.6" => -3, "1.9.1" => -2 }[RUBY_VERSION]
def caller_binding(skip=1)
TRACE_STACK[ VERSION_OFFSET - skip ][:binding]
end
set_trace_func(lambda do |event, file, line, id, binding, classname|
item = {:event=>event,:file=>file,:line=>line,:id=>id,:binding=>binding,:classname=>classname}
#p item
case(event)
when 'line'
TRACE_STACK.push(item) if TRACE_STACK.empty?
when /\b(?:(?:c-)?call|class)\b/
TRACE_STACK.push(item)
when /\b(?:(?:c-)?return|end|raise)\b/
TRACE_STACK.pop
end
end)

这适用于您的示例,但我还没有对它进行太多测试

require 'caller_binding'
class A
def some_method
x = 123
nonexistent_method
end
def method_missing( method, *args, &block )
b = caller_binding
eval "puts x", b
end
end

x = 456
A.new.some_method #=> prints 123
A.new.nonexistent_method #=> prints 456

当然,如果绑定(bind)没有定义您要评估的变量,这将不起作用,但这是绑定(bind)的普遍问题。如果 undefined variable ,则它不知道它是什么。

require 'caller_binding'
def show_x(b)
begin
eval <<-SCRIPT, b
puts "x = \#{x}"
SCRIPT
rescue => e
puts e
end
end

def y
show_x(caller_binding)
end

def ex1
y #=> prints "undefined local variable or method `x' for main:Object"
show_x(binding) #=> prints "undefined local variable or method `x' for main:Object"
end

def ex2
x = 123
y #+> prints "x = 123"
show_x(binding) #+> prints "x = 123"
end

ex1
ex2

要解决这个问题,您需要在评估的字符串中进行一些错误处理:

require 'caller_binding'
def show_x(b)
begin
eval <<-SCRIPT, b
if defined? x
puts "x = \#{x}"
else
puts "x not defined"
end
SCRIPT
rescue => e
puts e
end
end

def y
show_x(caller_binding)
end

def ex1
y #=> prints "x not defined"
show_x(binding) #=> prints "x not defined"
end

def ex2
x = 123
y #+> prints "x = 123"
show_x(binding) #+> prints "x = 123"
end

ex1
ex2

关于ruby - 如何从 method_missing 获取绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1314592/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com