Ruby 类变量与实例变量中遇到的问题

qinsicheng · August 29, 2023 · Last by qinsicheng replied at August 30, 2023 · 841 hits

当我想实现一个 (暂不考虑并发性) 单例模式的类时:

class Singleton
  private_class_method :new,:dup,:clone
  def self.instance
    @@single ||= new
  end
end

这时候我再用两个类去继承

class Config < Singleton
end
class Database < Singleton
end
p Config.instance        # => #<Config:0x0000000102a9eef0>
p Database.instance      # => #<Config:0x0000000102a9eef0>
p Config.instance.equal? Database.instance  # => true

当我执行两个继承类各自的.instance方法时,返回了同一个对象,这里我的理解是:

  1. 当执行Config.instance时,找的Singleton.instance并首次初始化类变量@@single,这里的类变量归属Singleton,而@@singleConfig的一个实例。
  2. 当执行Database.instance时,也执行到了Singleton.instance,由于@@single已经被赋值了,所以返回。

但这里我希望的是Config.instanceDatabase.instance各自返回的是各自的实例,所以将@@single改为@single,最终结果确实没问题:

class Singleton
  private_class_method :new,:dup,:clone
  def self.instance
    @single ||= new
  end
end
class Config < Singleton
end
class Database < Singleton
end
p Config.instance          # => #<Config:0x0000000100c8d5b0>
p Database.instance        # => #<Database:0x0000000100c8cae8>
p Config.instance.equal? Database.instance  # => false

但是我搞不明白,为什么变为实例变量@single时,结果发生了变化,@singleSingleton这个对象的实例变量,而这个Singleton这个类对象应该是唯一的,但结果是不同的?想请教一下

Config 往上找祖先,找到 self.instance 方法,然后执行方法的上下文是 Config,@single 属于 Config。

咋不试试自带的单例呢?我觉得会省心一点

class Config
  include Singleton
end

还是目的只是想玩玩类变量?

@@single 是 "类变量",@single 在类方法中是 "类实例变量",在实例方法中是 "实例变量" google 可以找到相关解释

Reply to hegwin

单纯是自己想搞明白区别😂

Reply to Rei

搞明白了,感谢

Reply to geekerzp

感谢感谢

qinsicheng closed this topic. 30 Aug 09:50
You need to Sign in before reply, if you don't have an account, please Sign up first.