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
をプライベートにして、ファクトリメソッドを介して呼び出したいと思います。
試したコードの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
クラスレベルのファクトリメソッドはプライベートnew
に問題なくアクセスできますが、new
はプライベートであるため、new
を使用して直接インスタンス化しようとすると失敗します。
使用法に光を当てるために、ファクトリメソッドの一般的な例を次に示します。
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')