gpt4 book ai didi

ruby - 使用 method_added ruby​​ 的堆栈级别太深

转载 作者:太空宇宙 更新时间:2023-11-03 17:20:06 25 4
gpt4 key购买 nike

我已经创建了一个模块来在类中的方法调用之前 Hook 方法:

module Hooks

def self.included(base)
base.send :extend, ClassMethods
end


module ClassMethods
# everytime we add a method to the class we check if we must redifine it
def method_added(method)
if @hooker_before.present? && @methods_to_hook_before.include?(method)
hooked_method = instance_method(@hooker_before)
@methods_to_hook_before.each do |method_name|
begin
method_to_hook = instance_method(method_name)
rescue NameError => e
return
end
define_method(method_name) do |*args, &block|
hooked_method.bind(self).call
method_to_hook.bind(self).(*args, &block) ## your old code in the method of the class
end
end
end
end

def before(*methods_to_hooks, hookers)
@methods_to_hook_before = methods_to_hooks
@hooker_before = hookers[:call]
end
end
end

我已将该模块包含在我的一个类中:

require_relative 'hooks'

class Block
include Indentation
include Hooks
attr_accessor :file, :indent
before :generate, call: :indent
# after :generate, call: :write_end

def initialize(file, indent=nil)
self.file = file
self.indent = indent
end

def generate
yield
end
end

此 Block 类是另一个类的父类,该类正在实现自己的生成方法版本并且实际已实现。

当我的代码运行时,method_added 实际上是用 method :generate 作为参数在某种无限循环中调用的。我不明白为什么 method_added 会陷入这个无限循环。你知道这段代码有什么问题吗?这是完整代码的链接: link to code on github

最佳答案

因为您在 method_added 中调用了 define_method,所以导致了无限递归。堆栈跟踪(不幸的是您没有提供)应该显示这一点。

解决这个问题的一个稍微丑陋的解决方法可能是显式设置一个变量(例如 @_adding_a_method)并将其用作 method_added 的保护子句:

module ClassMethods
def method_added(method)
return if @_adding_a_method

if @hooker_before.present? && @methods_to_hook_before.include?(method)
# ...

@_adding_a_method = true
define_method(method_name) do |*args, &block|
# ...
end
@_adding_a_method = false

# ...
end
end
end

但是,退一步说,我不太确定这个模块试图实现什么。难道你不能用 Module#prepend 来实现吗?而不是这种元编程?

这段代码让我想起了您可能会在有关高级元编程技术的旧 Ruby 1.8/1.9 教程中找到的内容; Module#prepend 在很大程度上使此类解决方法变得多余。

关于ruby - 使用 method_added ruby​​ 的堆栈级别太深,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53487250/

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