Подтвердить что ты не робот

Как сделать конструктор класса закрытым в Ruby?

class A
private
  def initialize
    puts "wtf?"
  end
end

A.new #still works and calls initialize

и

class A
private
  def self.new
    super.new
  end
end

не работает вообще

Так какой правильный путь? Я хочу сделать new private и вызвать его с помощью метода factory.

4b9b3361

Ответ 2

Второй кусок кода, который вы пытались, почти прав. Проблема заключается в том, что private работает в контексте методов экземпляра вместо методов класса.

Чтобы работать private или private :new, вам просто нужно заставить его быть в контексте методов класса, подобных этому:

class A
  class << self
    private :new
  end
end

Или, если вы действительно хотите переопределить new и вызвать super

class A
  class << self
    private
    def new(*args)
      super(*args)
      # additional code here
    end
  end
end

Методы класса factory класса могут получить доступ к закрытому new просто, но попытка создать экземпляр напрямую с помощью new завершится с ошибкой, потому что new является закрытым.

Ответ 3

Чтобы пролить свет на использование, вот общий пример метода factory:

class A
  def initialize(argument)
    # some initialize logic
  end

  # mark A.new constructor as private
  private_class_method :new

  # add a class level method that can return another type
  # (not exactly, but close to `static` keyword in other languages)
  def self.create(my_argument)
     # some logic
     # e.g. return an error object for invalid arguments
     return Result.error('bad argument') if(bad?(my_argument))

     # create new instance by calling private :new method
     instance = new(my_argument)
     Result.new(instance)
  end
end

Затем используйте его как

result = A.create('some argument')    

Как и ожидалось, ошибка времени выполнения возникает в случае прямого использования new:

a = A.new('this leads to the error')