objects - ruby scripting
¿Cómo hacer que el constructor de la clase sea privado en Ruby? (3)
class A
private
def initialize
puts "wtf?"
end
end
A.new #still works and calls initialize
y
class A
private
def self.new
super.new
end
end
no funciona del todo
Entonces, ¿cuál es la forma correcta? Quiero hacer un new
privado y llamarlo a través de un método de fábrica.
El segundo fragmento de código que probaste es casi correcto. El problema es private
está operando en el contexto de los métodos de instancia en lugar de los métodos de clase.
Para obtener private
o private :new
para trabajar, solo necesita forzarlo para que se encuentre en el contexto de métodos de clase como este:
class A
class << self
private :new
end
end
O, si realmente desea redefinir lo new
y llamar super
class A
class << self
private
def new(*args)
super(*args)
# additional code here
end
end
end
Los métodos de fábrica de nivel de clase pueden acceder al new
privado sin problemas, pero intentar crear una instancia directamente utilizando el new
fallará porque el new
es privado.
Para aclarar el uso, aquí hay un ejemplo común del método de fábrica:
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
Entonces utilízalo como
result = A.create(''some argument'')
Como se esperaba, el error de tiempo de ejecución se produce en el caso de un new
uso directo:
a = A.new(''this leads to the error'')