为什么在 Ruby 中使用 class 变量被视为 'code smell'?
Why is using a class variable in Ruby considered a 'code smell'?
根据 Reek,创建 class 变量被视为 'code smell'。这背后的解释是什么?
您可以在 Class Variables 上的文档中找到:
Class variables form part of the global runtime state, and as such make it easy for one part of the system to accidentally or inadvertently depend on another part of the system. So the system becomes more prone to problems where changing something over here breaks something over there. In particular, class variables can make it hard to set up tests (because the context of the test includes all global state).
本质上,它是全局状态的表现,几乎被普遍认为是 evil,因为它使测试更加困难并导致更脆弱的 class/program 结构。
This Stack Overflow question 也可能值得一读,它显示了 class 变量的主要问题:如果任何 class 继承自您的 class 并修改 class 变量,该变量的 每个 实例都会发生变化,甚至来自父变量!可以理解,这让您很容易搬起石头砸自己的脚,所以除非您非常小心,否则最好避免使用它们。
还值得将 class 变量与 class 实例变量进行比较。 This question 有几个很好的例子来说明用法差异,但本质上 class 变量是 共享的 ,而 class 实例变量是 未共享。因此,为了避免不必要的副作用,class 实例变量几乎总是你想要的。
简而言之,这:
class Shape
@@sides = 0
def self.sides
@@sides
end
end
class Pentagon < Shape
@@sides = 5
end
puts Shape.sides # oops ... prints 5
根据 Reek,创建 class 变量被视为 'code smell'。这背后的解释是什么?
您可以在 Class Variables 上的文档中找到:
Class variables form part of the global runtime state, and as such make it easy for one part of the system to accidentally or inadvertently depend on another part of the system. So the system becomes more prone to problems where changing something over here breaks something over there. In particular, class variables can make it hard to set up tests (because the context of the test includes all global state).
本质上,它是全局状态的表现,几乎被普遍认为是 evil,因为它使测试更加困难并导致更脆弱的 class/program 结构。
This Stack Overflow question 也可能值得一读,它显示了 class 变量的主要问题:如果任何 class 继承自您的 class 并修改 class 变量,该变量的 每个 实例都会发生变化,甚至来自父变量!可以理解,这让您很容易搬起石头砸自己的脚,所以除非您非常小心,否则最好避免使用它们。
还值得将 class 变量与 class 实例变量进行比较。 This question 有几个很好的例子来说明用法差异,但本质上 class 变量是 共享的 ,而 class 实例变量是 未共享。因此,为了避免不必要的副作用,class 实例变量几乎总是你想要的。
简而言之,这:
class Shape
@@sides = 0
def self.sides
@@sides
end
end
class Pentagon < Shape
@@sides = 5
end
puts Shape.sides # oops ... prints 5