Ответ 1
Попробуйте следующее:
class A
private_class_method :new
end
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.
Попробуйте следующее:
class A
private_class_method :new
end
Второй кусок кода, который вы пытались, почти прав. Проблема заключается в том, что 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
является закрытым.
Чтобы пролить свет на использование, вот общий пример метода 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')