Jak uczynić konstruktor klasy prywatnym w Ruby?

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

A.new #still works and calls initialize

I

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

Doesn ' t work all

Więc jaka jest właściwa droga? Chcę uczynić new prywatną i nazwać ją metodą fabryczną.
Author: Andrew Grimm, 2009-10-14

3 answers

Spróbuj tego:

class A
  private_class_method :new
end

Więcej o APIDock

 69
Author: adurity,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-16 21:47:00

Drugi fragment kodu, którego próbowałeś, jest prawie odpowiedni. Problem polega na tym, że private działa w kontekście metod instancji zamiast metod klas.

Aby uzyskać private lub private :new do pracy, wystarczy wymusić to w kontekście metod klasowych takich jak:

class A
  class << self
    private :new
  end
end

Lub, jeśli naprawdę chcesz przedefiniować new i zadzwonić super

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

Metody fabryczne poziomu klasy mogą uzyskać dostęp do prywatnego new bez problemu, ale próba utworzenia instancji bezpośrednio przy użyciu new nie powiedzie się ponieważ new jest prywatne.

 13
Author: Nathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-30 18:50:42

Aby rzucić trochę światła na użycie, oto popularny przykład metody fabrycznej:

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

Następnie użyj go jako

result = A.create('some argument')    

Zgodnie z oczekiwaniami, błąd runtime występuje w przypadku bezpośredniego użycia new:

a = A.new('this leads to the error')
 2
Author: Artru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-14 16:00:12