How to make the class constructor private in Ruby?

风流意气都作罢 提交于 2019-12-03 18:38:26

问题


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.


回答1:


Try this:

class A
  private_class_method :new
end

More on APIDock




回答2:


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.




回答3:


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


来源:https://stackoverflow.com/questions/1567400/how-to-make-the-class-constructor-private-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!