【问题标题】:Are Ruby class variables bad?Ruby 类变量不好吗?
【发布时间】:2015-11-17 16:39:28
【问题描述】:

当我实现“instance of”/singleton 类型模式时,RubyMine 通知说使用类变量被认为是错误的形式。

我遇到的唯一信息是使用类变量会使继承有点松散。以下代码会给我带来问题还有其他原因吗?

class Settings
  private_class_method :new
  attr_accessor :prop1
  attr_accessor :prop2

  @@instance = nil

  def Settings.instance_of
    @@instance = new unless @@instance
    @@instance
  end
  def initialize
    @prop2 = "random"
  end
end

另外,有没有更好的方法,Ruby-wise,来实现相同的目标,以确保只有一个实例?

【问题讨论】:

  • 方法体Settings.instance_of可以简化为@@instance ||= new
  • 你在这里问两个不同的问题:(1)类变量的使用不好(你的问题标题)?以及(2)如何创建单实例类(你的问题内容)?我引用了处理单实例想法的链接。但是你所拥有的并不是一个使用类变量的坏例子,它们也不是总是坏的。他们只是在大多数时候被滥用。我不会将您的示例归类为“滥用”。 :) 另一个使用类变量的相关示例可能是实例计数。
  • 这篇在 Practicing Ruby Ruby and the singleton pattern don't get along 上的文章对我来说是非常宝贵的参考。
  • 哇,感谢您的所有反馈 - 而且速度如此之快。我会阅读链接。另外,感谢@lurker 提供详细信息

标签: ruby singleton


【解决方案1】:

Ruby 中类变量的问题在于,当您从一个类继承时,新类不会获得其自己的类变量的新副本,而是使用从其继承的相同副本超类。

例如:

class Car
  @@default_max_speed = 100
  def self.default_max_speed
    @@default_max_speed
  end
end

class SuperCar < Car
  @@default_max_speed = 200 # and all cars in the world become turbo-charged
end

SuperCar.default_max_speed # returns 200, makes sense!
Car.default_max_speed # returns 200, oops!

推荐的做法是使用类实例变量(请记住,在 Ruby 中,类只是类 Class 的对象)。我强烈推荐阅读 Russ Olsen 的 Eloquent Ruby 第 14 章,其中详细介绍了这个主题。

【讨论】:

  • 感谢您的反馈。这几乎是我在研究中发现的,但这是一个很好的简洁描述。
【解决方案2】:

Ruby 类变量不好吗?像任何主观问题一样,它取决于您的观点。有大量关于全局变量主题的文献,其中单例类本质上是一种形式。能够在方法中调用包含在方法调用中不可见的状态的事物往往会使理解事物变得困难和维护问题。

对于 Ruby-1.9.3 及更高版本,请参阅文档以获得更好的方法:

http://ruby-doc.org/stdlib-2.2.3/libdoc/singleton/rdoc/Singleton.html

用您正在运行的任何版本的 Ruby 替换 -2.2.3。

基本上:

用法¶ ↑

To use Singleton, include the module in your class.

class Klass
   include Singleton
   # ...
end

单身不好吗?嗯,我从 2004 年开始就一直在使用 ruby​​,我只记得有一次我什至考虑过使用单例。而且我不记得细节,所以我推断我实际上并没有这样做。对单例的需求通常表明您正在解决的问题需要以更清晰的形式重新表述。

【讨论】:

    猜你喜欢
    • 2011-01-06
    • 1970-01-01
    • 2013-03-24
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 2013-04-18
    • 2021-07-29
    相关资源
    最近更新 更多