gpt4 book ai didi

ruby - 使用附加数据动态创建的类方法 : data is being lost

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

我有一个类,它被另一个类的方法动态扩展。这些方法中还有一些额外的静态信息,例如。例如:

class A
# @b = B.new # in initialize
def a
puts @b.info[:data][__callee__]
end
end

class B
attr_reader :info
@info = {:data => {:a => :method_name, …}}

def define_new_a name
A.class_eval %Q(
alias_method name, :a
)
@info[:data][name => :method_name]
end

define_new_a :a1
define_new_a :a2
end

这个别名方法 :a1 以某种方式依赖于 @info 结构(A 中的代码使用 B#info[:data ])。 @info 也可能在执行期间更新。一切正常,直到我第二次(第三次、第四次等)调用 A.new。在这种情况下,我有一个已经更新的 A 类定义,其中包含方法,例如 :a1:a2 (动态创建,)但是纯B#info 的新实例。

那么,问题是:

TL;DNR 让我们class 定义随时更改:需要动态地向其添加方法相关数据。类实例是长期创建的。有没有办法使当前类定义与相关数据同步

解释:我应该在哪里存储一些附加信息,例如info结构,以使其同步A 类的当前定义?使 B 成为单例并不是使 @@info 成为类变量的一种选择,因为它实际上可能在 A 的不同实例之间有所不同。实际上,引入了两个类只是为了澄清问题;可能有一个类同时具有 a) 动态创建的方法和 b) 这些方法所依赖的一些附加信息。带有散列 instance ⇒ info 的单例看起来有点多余而且完全不优雅。

另一个问题是是否有一种简单的方法来实例化类的版本,而无需任何动态创建(在当前长期运行期间)的东西?

提前致谢。

最佳答案

加载类 B 时,您对 A 调用两次 class_eval 以定义两个新方法。

所以不行:一旦 B 的定义被加载,A 的定义就不可撤销地改变了,你不能再访问它的原始定义。

解决方法是将 A 包装到一个类中,以保持原始功能不变:

class AFresh
# Your code
end

class A < AFresh
# Just inherit...
end

顺便说一句:您的设计似乎是依赖注入(inject)模式的一个非常糟糕的变体。如果是,请查看 Symfony 的依赖注入(inject)组件,以获取如何正确执行此操作的优秀示例。然后查看 Ruby 的内置 Forwardable 模块。

关于ruby - 使用附加数据动态创建的类方法 : data is being lost,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20213665/

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