62
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私有化并通过工厂方法调用它。

4

3 回答 3

95

试试这个:

class A
  private_class_method :new
end

更多关于 APIDock

于 2009-10-14T16:33:53.070 回答
13

您尝试的第二段代码几乎是正确的。问题是private在实例方法而不是类方法的上下文中操作。

要获取privateprivate :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是私有的。

于 2015-09-30T18:50:42.330 回答
13

为了阐明用法,下面是工厂方法的一个常见示例:

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')    

As expected, the runtime error occurs in the case of direct new usage:

a = A.new('this leads to the error')
于 2017-09-14T16:00:12.087 回答