red-o-alf
red-o-alf

Reputation: 3245

Does defining initialize for a singleton class make sense in Ruby?

I anticipate that I am not trying to do anything practical here, just trying to understand some deeper Ruby concepts.

Supppose I have the following code

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

I know it might not make sense or might be too intricately related on how Ruby internals work, but, if by chance anyone has been puzzled too by this and knows the answer... please share it :)

Upvotes: 2

Views: 1160

Answers (2)

Radi
Radi

Reputation: 696

In some cases, it does make sense to define a custom constructor, but I wouldn't call the method initialize, since the instance method you override to customise initialisation is also called initialize. That would be a little confusing.

def self.initialize # what would be this called on ?

If you define a method like this, you can invoke it by sending the method directly to the class:

Bookshelf.initialize

Same thing applies for methods defined inside class << self.

As mentioned, it does make sense to define custom constructors for a class. Sometimes just for readability's sake:

class Bookshelf
  attr_accessor :book_qty

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

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

Now you could instantiate a Bookshelf like this:

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

You actually call .new on the singleton class of Bookshelf. And #initialize is basically just a hook for the instance to tweak its initialisation.

How you could access class instance variables

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

Upvotes: 0

Max
Max

Reputation: 22325

There is no purpose to defining initialize for the singleton class (whether you use def self. or class << self). initialize is only called by Class#new and...

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

that's not allowed.

If you want code to be executed the first time a class is parsed, just put it in the class

class Bookshelf
  puts "class defined!"
end

Upvotes: 3

Related Questions