gpt4 book ai didi

ruby - 为什么我不应该扩展由 Struct.new 初始化的实例?

转载 作者:数据小太阳 更新时间:2023-10-29 06:38:09 26 4
gpt4 key购买 nike

我们有一个遗留代码库,其中 rubocop 报告了一些我永远无法理解的错误:

Don't extend an instance initialized by Struct.new. Extending it introduces a superfluous class level and may also introduce weird errors if the file is required multiple times.

究竟什么是“多余的类级别”,可能会引入什么样的“怪异错误”?

(问是因为显然我们在过去几年没有遇到过任何此类问题。)

最佳答案

Struct.new 创建一个匿名类,它恰好是 Struct 的子类:

s = Struct.new(:foo)
#=> #<Class:0x00007fdbc21a0270>

s.ancestors
#=> [#<Class:0x00007fdbc21a0270>, Struct, Enumerable, Object, Kernel, BasicObject]

您可以将该匿名类分配给常量以便为其命名:

Foo = Struct.new(:foo)
#=> Foo

Foo.ancestors
#=> [Foo, Struct, Enumerable, Object, Kernel, BasicObject]

这是创建 Struct 子类的常规方法。

另一方面,您的遗留代码似乎包含如下内容:

class Foo < Struct.new(:foo)
end

Struct.new 创建一个匿名类(它没有分配给常量)并且 Foo 将它子类化,结果是:

Foo.ancestors
#=> [Foo, #<Class:0x00007fee94191f38>, Struct, Enumerable, Object, Kernel, BasicObject]

显然,匿名类没有任何作用。

就像:

class Bar
end

class Foo < Bar # or Foo = Class.new(Bar)
end

Foo.ancestors
#=> [Foo, Bar, Object, Kernel, BasicObject]

相对于:

class Bar
end

class Foo < Class.new(Bar)
end

Foo.ancestors
#=> [Foo, #<Class:0x00007fdb870e7198>, Bar, Object, Kernel, BasicObject]

后一个示例中 Class.new(Bar) 返回的匿名类未分配给常量,因此既不使用也不需要。

关于ruby - 为什么我不应该扩展由 Struct.new 初始化的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49294676/

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