在Ruby中定义单例类的初始化是否有意义?

时间:2014-10-02 21:06:03

标签: ruby class internals

我预计我不会尝试在这里做任何实际的事情,只是试图理解一些更深层次的Ruby概念。

支持我有以下代码

class Bookshelf
  @book_qty = 100 # class instance var

  class << self
    attr_accessor :books_qty 
  end

  def initialize
    @book = "This book is in every object as an object instance variable"
  end

  # so far so good, but what happens with...

  def self.initialize   # what would be this called on ?
    puts " and at what step would this be printed, if ever?"
    # I thought it would be printed when the class code is parsed first time,
    # but no
  end

  # or also

  class << self
    def initialize
      puts "same here"
    end
  end

end

我知道它可能没有意义,或者可能与Ruby内部的工作方式有太多错综复杂的关联,但是,如果有人因此而感到困惑并知道答案......请分享:)

2 个答案:

答案 0 :(得分:3)

没有目的为单例类定义initialize(无论您使用def self.还是class << self)。 initialize仅由Class#new和...

调用
Bookshelf.singleton_class.new
# TypeError: can't create instance of singleton class

这是不允许的。

如果您希望在第一次解析类时执行代码,只需将其放在类

class Bookshelf
  puts "class defined!"
end

答案 1 :(得分:0)

在某些情况下,定义自定义构造函数是有意义的,但我不会调用方法initialize,因为您重写以自定义初始化的实例方法也称为initialize。那会有点混乱。

  

def self.initialize#这会被叫什么?

如果您定义这样的方法,可以通过将方法直接发送到类来调用它:

Bookshelf.initialize

同样适用于class << self中定义的方法。

如前所述,为类定义自定义构造函数确实有意义。有时只是出于可读性的考虑:

class Bookshelf
  attr_accessor :book_qty

  def self.with_quantity(quantity)
    new(quantity)
  end

  def initialize(quantity)
    self.book_qty = quantity
  end
end

现在您可以像这样实例化一个Bookshelf:

bs = Bookshelf.with_quantity 100
bs.quantity # => 100

您实际上在.new的单例类上调用了Bookshelf#initialize基本上只是实例调整初始化的一个钩子。

如何访问类实例变量

class Bookshelf
  @book_qty = 1000
  class << self
    attr_accessor :book_qty
  end
end

Bookshelf.book_qty # => 1000
Bookshelf.book_qty = 2000
Bookshelf.book_qty # => 2000