如何在 Ruby 中将类构造函数设为私有?

发布于 2024-08-08 05:36:42 字数 287 浏览 12 评论 0原文

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

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

A.new #still works and calls initialize

and

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

doesn't work altogether

So what's the correct way? I want to make new private and call it via a factory method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

偏爱你一生 2024-08-15 05:36:42

试试这个:

class A
  private_class_method :new
end

有关 APIDock 的更多信息

Try this:

class A
  private_class_method :new
end

More on APIDock

古镇旧梦 2024-08-15 05:36:42

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

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

To shed some light on the usage, here is a common example of the factory method:

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

Then use it as

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')
复古式 2024-08-15 05:36:42

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

要让 privateprivate :new 工作,您只需强制它位于类方法的上下文中,如下所示:

class A
  class << self
    private :new
  end
end

或者,如果您确实想重新定义 < code>new 并调用 super

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

类级工厂方法可以访问私有的 new 就好了,但是尝试直接使用 new 实例化> 将失败,因为 new 是私有的。

The second chunk of code you tried is almost right. The problem is private is operating in the context of instance methods instead of class methods.

To get private or private :new to work, you just need to force it to be in the context of class methods like this:

class A
  class << self
    private :new
  end
end

Or, if you truly want to redefine new and call super

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

Class-level factory methods can access the private new just fine, but trying to instantiate directly using new will fail because new is private.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文