gpt4 book ai didi

ruby - 为什么 singleton_class 对象在 Ruby 2.4 而不是在 2.3 中卡住?

转载 作者:数据小太阳 更新时间:2023-10-29 08:57:30 27 4
gpt4 key购买 nike

我们有一个应用程序使用 Sequel gem 连接到数据源,执行一些工作,然后返回一个结果,该结果具有许多附加到该对象的 singleton_class 的便捷方法。在 ruby​​ 2.3 中,此代码按预期工作:

result = EpulseDB::Employee.where(normalized_args)
result.singleton_class.include(EpulseNormalization)

我们可以看到使用 ruby​​ 2.3.4 singleton_class 没有被卡住:

[1] pry(main)> result = EpulseDB::Employee.where(employee_id: 2)
=> #<Sequel::Postgres::Dataset: "SELECT * FROM \"employee\" WHERE (\"employee_id\" = 2)">
[2] pry(main)> result.frozen?
=> true
[3] pry(main)> result.singleton_class.frozen?
=> false
[4] pry(main)> result.singleton_class.include(EpulseNormalization)
=> #<Class:#<Sequel::Postgres::Dataset:0x007feff0903660>>

但在 Ruby 2.4.2 中,singleton_class 似乎被卡住返回,我们无法再扩展它。有没有我应该使用的扩展单例的新方法??

[1] pry(main)> result = EpulseDB::Employee.where(employee_id: 2)
=> #<Sequel::Postgres::Dataset: "SELECT * FROM \"employee\" WHERE (\"employee_id\" = 2)">
[2] pry(main)> result.frozen?
=> true
[3] pry(main)> result.singleton_class.frozen?
=> true
[4] pry(main)> result.singleton_class.include(EpulseNormalization)
RuntimeError: can't modify frozen object
from (pry):4:in `append_features'

最佳答案

使用 Dataset#with_extend 返回使用模块扩展的数据集的修改副本,而不是调用 Dataset#extend 来修改数据集本身。这适用于 Sequel 支持的所有 ruby​​ 版本。

背景:这与 Ruby 本身无关,这是由于 Sequel 中针对 Ruby <2.4 中缺少功能的解决方法。

在 Ruby <2.4 中,Object#freeze 无法处理 Object#clone 用于创建卡住对象的修改副本(包括对象的单例副本)的情况类(class))。 Ruby 2.4 向 Object#clone 添加了 freeze: false 选项,以允许创建卡住对象的修改副本,包括它们的单例类(参见 https://bugs.ruby-lang.org/issues/12300 )。

Sequel::Dataset 在内部使用 #clone 来返回修改后的数据集,并且要求数据集包含用于正常运行的任何单例类的副本。因为我希望 Sequel::Dataset 被卡住,但仍然在 ruby​​ < 2.4 上工作,所以它基本上假装在 ruby​​ <2.4 上被卡住。它只在 ruby​​ 2.4 中真正卡住。见:

关于ruby - 为什么 singleton_class 对象在 Ruby 2.4 而不是在 2.3 中卡住?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47760253/

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